aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-04-19 01:05:26 +0000
committerChris Lattner <sabre@nondot.org>2009-04-19 01:05:26 +0000
commit04ea2b633a1f8ee662b8a99d2903a11c1b68e1ed (patch)
tree1e8c2bdd44eaee693e5eb01edea9d42081d666a6 /lib/Sema/SemaDecl.cpp
parentad56d684259f706b7c0ae5ad9c23adb4f2926817 (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.cpp28
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;
}
}