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

Reid Kleckner reid at kleckner.net
Mon Feb 2 14:15:31 PST 2015


Author: rnk
Date: Mon Feb  2 16:15:31 2015
New Revision: 227876

URL: http://llvm.org/viewvc/llvm-project?rev=227876&view=rev
Log:
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.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Sema/ScopeInfo.h
    cfe/trunk/lib/Sema/ScopeInfo.cpp
    cfe/trunk/lib/Sema/SemaStmt.cpp
    cfe/trunk/test/SemaCXX/exceptions-seh.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=227876&r1=227875&r2=227876&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Feb  2 16:15:31 2015
@@ -5447,6 +5447,10 @@ def err_exceptions_disabled : Error<
   "cannot use '%0' with exceptions disabled">;
 def err_objc_exceptions_disabled : Error<
   "cannot use '%0' with Objective-C exceptions disabled">;
+def err_mixing_cxx_try_seh_try : Error<
+  "cannot use C++ 'try' in the same function as SEH '__try'">;
+def note_conflicting_try_here : Note<
+  "conflicting %0 here">;
 def warn_non_virtual_dtor : Warning<
   "%0 has virtual functions but non-virtual destructor">,
   InGroup<NonVirtualDtor>, DefaultIgnore;

Modified: cfe/trunk/include/clang/Sema/ScopeInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/ScopeInfo.h?rev=227876&r1=227875&r2=227876&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/ScopeInfo.h (original)
+++ cfe/trunk/include/clang/Sema/ScopeInfo.h Mon Feb  2 16:15:31 2015
@@ -124,6 +124,12 @@ public:
   /// false if there is an invocation of an initializer on 'self'.
   bool ObjCWarnForNoInitDelegation;
 
+  /// First C++ 'try' statement in the current function.
+  SourceLocation FirstCXXTryLoc;
+
+  /// First SEH '__try' statement in the current function.
+  SourceLocation FirstSEHTryLoc;
+
   /// \brief Used to determine if errors occurred in this function or block.
   DiagnosticErrorTrap ErrorTrap;
 
@@ -321,6 +327,16 @@ public:
     HasDroppedStmt = true;
   }
 
+  void setHasCXXTry(SourceLocation TryLoc) {
+    setHasBranchProtectedScope();
+    FirstCXXTryLoc = TryLoc;
+  }
+
+  void setHasSEHTry(SourceLocation TryLoc) {
+    setHasBranchProtectedScope();
+    FirstSEHTryLoc = TryLoc;
+  }
+
   bool NeedsScopeChecking() const {
     return !HasDroppedStmt &&
         (HasIndirectGoto ||

Modified: cfe/trunk/lib/Sema/ScopeInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/ScopeInfo.cpp?rev=227876&r1=227875&r2=227876&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/ScopeInfo.cpp (original)
+++ cfe/trunk/lib/Sema/ScopeInfo.cpp Mon Feb  2 16:15:31 2015
@@ -33,6 +33,8 @@ void FunctionScopeInfo::Clear() {
   ObjCWarnForNoDesignatedInitChain = false;
   ObjCIsSecondaryInit = false;
   ObjCWarnForNoInitDelegation = false;
+  FirstCXXTryLoc = SourceLocation();
+  FirstSEHTryLoc = SourceLocation();
 
   SwitchStack.clear();
   Returns.clear();

Modified: cfe/trunk/lib/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=227876&r1=227875&r2=227876&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Mon Feb  2 16:15:31 2015
@@ -3303,6 +3303,13 @@ StmtResult Sema::ActOnCXXTryBlock(Source
   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 @@ StmtResult Sema::ActOnCXXTryBlock(Source
     }
   }
 
-  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 @@ StmtResult Sema::ActOnCXXTryBlock(Source
   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'";
+  }
+
+  getCurFunction()->setHasSEHTry(TryLoc);
 
-  return SEHTryStmt::Create(Context,IsCXXTry,TryLoc,TryBlock,Handler);
+  return SEHTryStmt::Create(Context, IsCXXTry, TryLoc, TryBlock, Handler);
 }
 
 StmtResult

Modified: cfe/trunk/test/SemaCXX/exceptions-seh.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/exceptions-seh.cpp?rev=227876&r1=227875&r2=227876&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/exceptions-seh.cpp (original)
+++ cfe/trunk/test/SemaCXX/exceptions-seh.cpp Mon Feb  2 16:15:31 2015
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-windows-msvc -fms-extensions -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -fms-extensions -fsyntax-only -fexceptions -fcxx-exceptions -verify %s
 
 // Basic usage should work.
 int safe_div(int n, int d) {
@@ -46,3 +46,25 @@ void inject_builtins() {
   func_template<void *, __exception_info>();
   func_template<unsigned long, __exception_code>();
 }
+
+void use_seh_after_cxx() {
+  try { // expected-note {{conflicting 'try' here}}
+    might_crash();
+  } catch (int) {
+  }
+  __try { // expected-error {{cannot use C++ 'try' in the same function as SEH '__try'}}
+    might_crash();
+  } __except(1) {
+  }
+}
+
+void use_cxx_after_seh() {
+  __try { // expected-note {{conflicting '__try' here}}
+    might_crash();
+  } __except(1) {
+  }
+  try { // expected-error {{cannot use C++ 'try' in the same function as SEH '__try'}}
+    might_crash();
+  } catch (int) {
+  }
+}





More information about the cfe-commits mailing list