diff options
author | Reid Kleckner <reid@kleckner.net> | 2015-02-02 22:15:31 +0000 |
---|---|---|
committer | Reid Kleckner <reid@kleckner.net> | 2015-02-02 22:15:31 +0000 |
commit | e71759103e72dae502775ce97c97c3d2bd3ef8c2 (patch) | |
tree | 1031be7199deeb41bab0cb7f7825efb1de2ca4ad /clang/lib/Sema | |
parent | 78b7d5fab22e2be356b80c6b01a2cc498fb9123c (diff) | |
download | bcm5719-llvm-e71759103e72dae502775ce97c97c3d2bd3ef8c2.tar.gz bcm5719-llvm-e71759103e72dae502775ce97c97c3d2bd3ef8c2.zip |
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
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/ScopeInfo.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaStmt.cpp | 28 |
2 files changed, 22 insertions, 8 deletions
diff --git a/clang/lib/Sema/ScopeInfo.cpp b/clang/lib/Sema/ScopeInfo.cpp index 63ef3b2355f..f80eadf18d5 100644 --- a/clang/lib/Sema/ScopeInfo.cpp +++ b/clang/lib/Sema/ScopeInfo.cpp @@ -33,6 +33,8 @@ void FunctionScopeInfo::Clear() { ObjCWarnForNoDesignatedInitChain = false; ObjCIsSecondaryInit = false; ObjCWarnForNoInitDelegation = false; + FirstCXXTryLoc = SourceLocation(); + FirstSEHTryLoc = SourceLocation(); SwitchStack.clear(); Returns.clear(); diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 22ed9308206..d17cf227011 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -3303,6 +3303,13 @@ StmtResult Sema::ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock, 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(SourceLocation TryLoc, Stmt *TryBlock, } } - 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(SourceLocation TryLoc, Stmt *TryBlock, 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 |