diff options
author | Chris Lattner <sabre@nondot.org> | 2009-04-19 01:05:26 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-04-19 01:05:26 +0000 |
commit | 04ea2b633a1f8ee662b8a99d2903a11c1b68e1ed (patch) | |
tree | 1e8c2bdd44eaee693e5eb01edea9d42081d666a6 /lib/Sema/SemaDecl.cpp | |
parent | ad56d684259f706b7c0ae5ad9c23adb4f2926817 (diff) |
First half of jump scope checking for indirect goto.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69498 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index ac97413634..2aaa1bc940 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -3001,7 +3001,8 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned ParentScope) { if (SubStmt == 0) continue; // FIXME: diagnose jumps past initialization: required in C++, warning in C. - // { int X = 4; L: } goto L; + // goto L; int X = 4; L: ; + // FIXME: what about jumps into C++ catch blocks, what are the rules? // If this is a declstmt with a VLA definition, it defines a scope from here // to the end of the containing context. @@ -3054,7 +3055,6 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned ParentScope) { continue; } - // FIXME: what about jumps into C++ catch blocks, what are the rules? // Recursively walk the AST. BuildScopeInformation(SubStmt, ParentScope); @@ -3068,7 +3068,10 @@ void JumpScopeChecker::VerifyJumps() { if (GotoStmt *GS = dyn_cast<GotoStmt>(Jump)) { CheckJump(GS, GS->getLabel(), GS->getGotoLoc(), diag::err_goto_into_protected_scope); - } else if (SwitchStmt *SS = dyn_cast<SwitchStmt>(Jump)) { + continue; + } + + if (SwitchStmt *SS = dyn_cast<SwitchStmt>(Jump)) { for (SwitchCase *SC = SS->getSwitchCaseList(); SC; SC = SC->getNextSwitchCase()) { assert(LabelAndGotoScopes.count(SC) && "Case not visited?"); @@ -3076,11 +3079,22 @@ void JumpScopeChecker::VerifyJumps() { diag::err_switch_into_protected_scope); } continue; - } else { - assert(isa<IndirectGotoStmt>(Jump)); - // FIXME: Emit an error on indirect gotos when not in scope 0. - continue; } + + + // We don't know where an indirect goto goes, require that it be at the + // top level of scoping. + assert(isa<IndirectGotoStmt>(Jump)); + assert(LabelAndGotoScopes.count(Jump) &&"Jump didn't get added to scopes?"); + unsigned GotoScope = LabelAndGotoScopes[Jump]; + if (GotoScope == 0) continue; + S.Diag(Jump->getLocStart(), diag::err_indirect_goto_in_protected_scope); + + while (GotoScope != 0) { + S.Diag(Scopes[GotoScope].Loc, Scopes[GotoScope].Diag); + GotoScope = Scopes[GotoScope].ParentScope; + } + continue; } } |