diff options
author | dim <dim@FreeBSD.org> | 2015-05-27 18:47:56 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2015-05-27 18:47:56 +0000 |
commit | 3191b2b32a96e1a6ee833fcca73e5c8e0c67ba65 (patch) | |
tree | dbbd4047878da71c1a706e26ce05b4e7791b14cc /lib/Sema/JumpDiagnostics.cpp | |
parent | 38d6f2e7f2ce51a5b3836d26596c6c34a3288752 (diff) | |
download | FreeBSD-src-3191b2b32a96e1a6ee833fcca73e5c8e0c67ba65.zip FreeBSD-src-3191b2b32a96e1a6ee833fcca73e5c8e0c67ba65.tar.gz |
Vendor import of clang trunk r238337:
https://llvm.org/svn/llvm-project/cfe/trunk@238337
Diffstat (limited to 'lib/Sema/JumpDiagnostics.cpp')
-rw-r--r-- | lib/Sema/JumpDiagnostics.cpp | 55 |
1 files changed, 50 insertions, 5 deletions
diff --git a/lib/Sema/JumpDiagnostics.cpp b/lib/Sema/JumpDiagnostics.cpp index fd75c02..aac28be 100644 --- a/lib/Sema/JumpDiagnostics.cpp +++ b/lib/Sema/JumpDiagnostics.cpp @@ -338,6 +338,36 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned &origParentScope) return; } + case Stmt::SEHTryStmtClass: { + SEHTryStmt *TS = cast<SEHTryStmt>(S); + unsigned newParentScope; + Scopes.push_back(GotoScope(ParentScope, + diag::note_protected_by_seh_try, + diag::note_exits_seh_try, + TS->getSourceRange().getBegin())); + if (Stmt *TryBlock = TS->getTryBlock()) + BuildScopeInformation(TryBlock, (newParentScope = Scopes.size()-1)); + + // Jump from __except or __finally into the __try are not allowed either. + if (SEHExceptStmt *Except = TS->getExceptHandler()) { + Scopes.push_back(GotoScope(ParentScope, + diag::note_protected_by_seh_except, + diag::note_exits_seh_except, + Except->getSourceRange().getBegin())); + BuildScopeInformation(Except->getBlock(), + (newParentScope = Scopes.size()-1)); + } else if (SEHFinallyStmt *Finally = TS->getFinallyHandler()) { + Scopes.push_back(GotoScope(ParentScope, + diag::note_protected_by_seh_finally, + diag::note_exits_seh_finally, + Finally->getSourceRange().getBegin())); + BuildScopeInformation(Finally->getBlock(), + (newParentScope = Scopes.size()-1)); + } + + return; + } + default: break; } @@ -417,7 +447,8 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned &origParentScope) unsigned newParentScope; // Disallow jumps into the protected statement of an @synchronized, but // allow jumps into the object expression it protects. - if (ObjCAtSynchronizedStmt *AS = dyn_cast<ObjCAtSynchronizedStmt>(SubStmt)){ + if (ObjCAtSynchronizedStmt *AS = + dyn_cast<ObjCAtSynchronizedStmt>(SubStmt)) { // Recursively walk the AST for the @synchronized object expr, it is // evaluated in the normal scope. BuildScopeInformation(AS->getSynchExpr(), ParentScope); @@ -434,14 +465,16 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned &origParentScope) } // Disallow jumps into the protected statement of an @autoreleasepool. - if (ObjCAutoreleasePoolStmt *AS = dyn_cast<ObjCAutoreleasePoolStmt>(SubStmt)){ - // Recursively walk the AST for the @autoreleasepool part, protected by a new - // scope. + if (ObjCAutoreleasePoolStmt *AS = + dyn_cast<ObjCAutoreleasePoolStmt>(SubStmt)) { + // Recursively walk the AST for the @autoreleasepool part, protected by a + // new scope. Scopes.push_back(GotoScope(ParentScope, diag::note_protected_by_objc_autoreleasepool, diag::note_exits_objc_autoreleasepool, AS->getAtLoc())); - BuildScopeInformation(AS->getSubStmt(), (newParentScope = Scopes.size()-1)); + BuildScopeInformation(AS->getSubStmt(), + (newParentScope = Scopes.size() - 1)); continue; } @@ -756,6 +789,18 @@ void JumpScopeChecker::CheckJump(Stmt *From, Stmt *To, SourceLocation DiagLoc, // Common case: exactly the same scope, which is fine. if (FromScope == ToScope) return; + // Warn on gotos out of __finally blocks. + if (isa<GotoStmt>(From) || isa<IndirectGotoStmt>(From)) { + // If FromScope > ToScope, FromScope is more nested and the jump goes to a + // less nested scope. Check if it crosses a __finally along the way. + for (unsigned I = FromScope; I > ToScope; I = Scopes[I].ParentScope) { + if (Scopes[I].InDiag == diag::note_protected_by_seh_finally) { + S.Diag(From->getLocStart(), diag::warn_jump_out_of_seh_finally); + break; + } + } + } + unsigned CommonScope = GetDeepestCommonScope(FromScope, ToScope); // It's okay to jump out from a nested scope. |