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