diff options
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/JumpDiagnostics.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Sema/Scope.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 38 |
3 files changed, 45 insertions, 0 deletions
diff --git a/clang/lib/Sema/JumpDiagnostics.cpp b/clang/lib/Sema/JumpDiagnostics.cpp index fd75c02bb1e..9a9215174ba 100644 --- a/clang/lib/Sema/JumpDiagnostics.cpp +++ b/clang/lib/Sema/JumpDiagnostics.cpp @@ -338,6 +338,10 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned &origParentScope) return; } + case Stmt::SEHTryStmtClass: + // FIXME: Implement jump diagnostics for bad SEH jumps. + break; + default: break; } diff --git a/clang/lib/Sema/Scope.cpp b/clang/lib/Sema/Scope.cpp index 6c797788238..eeb2e01781e 100644 --- a/clang/lib/Sema/Scope.cpp +++ b/clang/lib/Sema/Scope.cpp @@ -185,6 +185,9 @@ void Scope::dumpImpl(raw_ostream &OS) const { } else if (Flags & SEHTryScope) { OS << "SEHTryScope"; Flags &= ~SEHTryScope; + } else if (Flags & SEHExceptScope) { + OS << "SEHExceptScope"; + Flags &= ~SEHExceptScope; } else if (Flags & OpenMPDirectiveScope) { OS << "OpenMPDirectiveScope"; Flags &= ~OpenMPDirectiveScope; diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index a070944ddb9..c28325a790e 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -202,6 +202,28 @@ static bool SemaBuiltinCallWithStaticChain(Sema &S, CallExpr *BuiltinCall) { return false; } +static bool SemaBuiltinSEHScopeCheck(Sema &SemaRef, CallExpr *TheCall, + Scope::ScopeFlags NeededScopeFlags, + unsigned DiagID) { + // Scopes aren't available during instantiation. Fortunately, builtin + // functions cannot be template args so they cannot be formed through template + // instantiation. Therefore checking once during the parse is sufficient. + if (!SemaRef.ActiveTemplateInstantiations.empty()) + return false; + + Scope *S = SemaRef.getCurScope(); + while (S && !S->isSEHExceptScope()) + S = S->getParent(); + if (!S || !(S->getFlags() & NeededScopeFlags)) { + auto *DRE = cast<DeclRefExpr>(TheCall->getCallee()->IgnoreParenCasts()); + SemaRef.Diag(TheCall->getExprLoc(), DiagID) + << DRE->getDecl()->getIdentifier(); + return true; + } + + return false; +} + ExprResult Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, CallExpr *TheCall) { @@ -461,6 +483,22 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, if (SemaBuiltinCallWithStaticChain(*this, TheCall)) return ExprError(); break; + + case Builtin::BI__exception_code: + case Builtin::BI_exception_code: { + if (SemaBuiltinSEHScopeCheck(*this, TheCall, Scope::SEHExceptScope, + diag::err_seh___except_block)) + return ExprError(); + break; + } + case Builtin::BI__exception_info: + case Builtin::BI_exception_info: { + if (SemaBuiltinSEHScopeCheck(*this, TheCall, Scope::SEHFilterScope, + diag::err_seh___except_filter)) + return ExprError(); + break; + } + } // Since the target specific builtins for each arch overlap, only check those |