SEH: Diagnose use of C++ EH and SEH in the same function

This check does not apply when Borland extensions are enabled, as they
have a checked in test case indicating that mixed usage of SEH and C++
is supported.

llvm-svn: 227876
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 22ed930..d17cf22 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -3303,6 +3303,13 @@
   if (getCurScope() && getCurScope()->isOpenMPSimdDirectiveScope())
     Diag(TryLoc, diag::err_omp_simd_region_cannot_use_stmt) << "try";
 
+  // C++ try is incompatible with SEH __try.
+  if (!getLangOpts().Borland && getCurFunction()->FirstSEHTryLoc.isValid()) {
+    Diag(TryLoc, diag::err_mixing_cxx_try_seh_try);
+    Diag(getCurFunction()->FirstSEHTryLoc, diag::note_conflicting_try_here)
+        << "'__try'";
+  }
+
   const unsigned NumHandlers = Handlers.size();
   assert(NumHandlers > 0 &&
          "The parser shouldn't call this if there are no handlers.");
@@ -3345,7 +3352,7 @@
     }
   }
 
-  getCurFunction()->setHasBranchProtectedScope();
+  getCurFunction()->setHasCXXTry(TryLoc);
 
   // FIXME: We should detect handlers that cannot catch anything because an
   // earlier handler catches a superclass. Need to find a method that is not
@@ -3356,16 +3363,21 @@
   return CXXTryStmt::Create(Context, TryLoc, TryBlock, Handlers);
 }
 
-StmtResult
-Sema::ActOnSEHTryBlock(bool IsCXXTry,
-                       SourceLocation TryLoc,
-                       Stmt *TryBlock,
-                       Stmt *Handler) {
+StmtResult Sema::ActOnSEHTryBlock(bool IsCXXTry, SourceLocation TryLoc,
+                                  Stmt *TryBlock, Stmt *Handler) {
   assert(TryBlock && Handler);
 
-  getCurFunction()->setHasBranchProtectedScope();
+  // SEH __try is incompatible with C++ try. Borland appears to support this,
+  // however.
+  if (!getLangOpts().Borland && getCurFunction()->FirstCXXTryLoc.isValid()) {
+    Diag(TryLoc, diag::err_mixing_cxx_try_seh_try);
+    Diag(getCurFunction()->FirstCXXTryLoc, diag::note_conflicting_try_here)
+        << "'try'";
+  }
 
-  return SEHTryStmt::Create(Context,IsCXXTry,TryLoc,TryBlock,Handler);
+  getCurFunction()->setHasSEHTry(TryLoc);
+
+  return SEHTryStmt::Create(Context, IsCXXTry, TryLoc, TryBlock, Handler);
 }
 
 StmtResult