diff options
author | Nico Weber <nicolasweber@gmx.de> | 2015-03-09 04:27:56 +0000 |
---|---|---|
committer | Nico Weber <nicolasweber@gmx.de> | 2015-03-09 04:27:56 +0000 |
commit | eb0cfb5ab0bcd3c794aaf1425b38ef165d64eabb (patch) | |
tree | f11cdd887e6b2a8feae59ebb743cd3dbe48393f4 /clang/lib/Sema/JumpDiagnostics.cpp | |
parent | 5768e9fde95e03a0fc5388a7814670cee1ae21e9 (diff) | |
download | bcm5719-llvm-eb0cfb5ab0bcd3c794aaf1425b38ef165d64eabb.tar.gz bcm5719-llvm-eb0cfb5ab0bcd3c794aaf1425b38ef165d64eabb.zip |
Warn when jumping out of a __finally block via goto.
This only warns on direct gotos and indirect gotos with a unique label
(`goto *&&label;`). Jumping out ith a true indirect goto is already an error.
This isn't O(1), but goto statements are less common than continue, break, and
return. Also, the GetDeepestCommonScope() call in the same function does the
same amount of work, so this isn't worse than what's there in a complexity
sense, and it should be pretty fast in practice.
This is the last piece that was missing in r231623.
llvm-svn: 231628
Diffstat (limited to 'clang/lib/Sema/JumpDiagnostics.cpp')
-rw-r--r-- | clang/lib/Sema/JumpDiagnostics.cpp | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/clang/lib/Sema/JumpDiagnostics.cpp b/clang/lib/Sema/JumpDiagnostics.cpp index 03fcc9482e0..aac28bedfa5 100644 --- a/clang/lib/Sema/JumpDiagnostics.cpp +++ b/clang/lib/Sema/JumpDiagnostics.cpp @@ -789,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. |