Index: lib/Sema/AnalysisBasedWarnings.cpp
===================================================================
--- lib/Sema/AnalysisBasedWarnings.cpp	(revision 220380)
+++ lib/Sema/AnalysisBasedWarnings.cpp	(working copy)
@@ -530,8 +530,17 @@
   if (CD.checkDiagnostics(Diags, ReturnsVoid, HasNoReturn))
       return;
 
-  // FIXME: Function try block
-  if (const CompoundStmt *Compound = dyn_cast<CompoundStmt>(Body)) {
+  SourceLocation LBrace, RBrace;
+  if (const auto *C = dyn_cast<CompoundStmt>(Body)) {
+    LBrace = C->getLBracLoc();
+    RBrace = C->getRBracLoc();
+  } else if (const auto *T = dyn_cast<CXXTryStmt>(Body)) {
+    LBrace = T->getLocStart();
+    RBrace = T->getLocEnd();
+  }
+
+  if (LBrace.isValid() && RBrace.isValid()) {
+    // Either in a function body compound statement, or a function-try-block.
     switch (CheckFallThrough(AC)) {
       case UnknownFallThrough:
         break;
@@ -538,30 +547,24 @@
 
       case MaybeFallThrough:
         if (HasNoReturn)
-          S.Diag(Compound->getRBracLoc(),
-                 CD.diag_MaybeFallThrough_HasNoReturn);
+          S.Diag(RBrace, CD.diag_MaybeFallThrough_HasNoReturn);
         else if (!ReturnsVoid)
-          S.Diag(Compound->getRBracLoc(),
-                 CD.diag_MaybeFallThrough_ReturnsNonVoid);
+          S.Diag(RBrace, CD.diag_MaybeFallThrough_ReturnsNonVoid);
         break;
       case AlwaysFallThrough:
         if (HasNoReturn)
-          S.Diag(Compound->getRBracLoc(),
-                 CD.diag_AlwaysFallThrough_HasNoReturn);
+          S.Diag(RBrace, CD.diag_AlwaysFallThrough_HasNoReturn);
         else if (!ReturnsVoid)
-          S.Diag(Compound->getRBracLoc(),
-                 CD.diag_AlwaysFallThrough_ReturnsNonVoid);
+          S.Diag(RBrace, CD.diag_AlwaysFallThrough_ReturnsNonVoid);
         break;
       case NeverFallThroughOrReturn:
         if (ReturnsVoid && !HasNoReturn && CD.diag_NeverFallThroughOrReturn) {
           if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
-            S.Diag(Compound->getLBracLoc(), CD.diag_NeverFallThroughOrReturn)
-              << 0 << FD;
+            S.Diag(LBrace, CD.diag_NeverFallThroughOrReturn) << 0 << FD;
           } else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
-            S.Diag(Compound->getLBracLoc(), CD.diag_NeverFallThroughOrReturn)
-              << 1 << MD;
+            S.Diag(LBrace, CD.diag_NeverFallThroughOrReturn) << 1 << MD;
           } else {
-            S.Diag(Compound->getLBracLoc(), CD.diag_NeverFallThroughOrReturn);
+            S.Diag(LBrace, CD.diag_NeverFallThroughOrReturn);
           }
         }
         break;
Index: test/SemaCXX/return-noreturn.cpp
===================================================================
--- test/SemaCXX/return-noreturn.cpp	(revision 220380)
+++ test/SemaCXX/return-noreturn.cpp	(working copy)
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 %s -fsyntax-only -verify -Wreturn-type -Wmissing-noreturn -Wno-unreachable-code -Wno-covered-switch-default
-// RUN: %clang_cc1 %s -fsyntax-only -std=c++11 -verify -Wreturn-type -Wmissing-noreturn -Wno-unreachable-code -Wno-covered-switch-default
+// RUN: %clang_cc1 %s -fsyntax-only -fcxx-exceptions -verify -Wreturn-type -Wmissing-noreturn -Wno-unreachable-code -Wno-covered-switch-default
+// RUN: %clang_cc1 %s -fsyntax-only -fcxx-exceptions -std=c++11 -verify -Wreturn-type -Wmissing-noreturn -Wno-unreachable-code -Wno-covered-switch-default
 
 // A destructor may be marked noreturn and should still influence the CFG.
 void pr6884_abort() __attribute__((noreturn));
@@ -245,3 +245,20 @@
   } // ok, initialization of lambda does not return
 }
 #endif
+
+// Ensure that function-try-blocks also check for return values properly.
+int functionTryBlock1(int s) try {
+  return 0;
+} catch (...) {
+} // expected-warning {{control may reach end of non-void function}}
+
+int functionTryBlock2(int s) try {
+} catch (...) {
+  return 0;
+} // expected-warning {{control may reach end of non-void function}}
+
+int functionTryBlock3(int s) try {
+  return 0;
+} catch (...) {
+  return 0;
+} // ok, both paths return.
