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 | 0bf2dd2ed408cbb662fd84adb7803035c9c61e9a (patch) | |
tree | 09f699871984dfd80d1814816200dab18a8389af /clang | |
parent | 34d9a5189222602540fd8a20ede94bf18a294f9a (diff) | |
download | bcm5719-llvm-0bf2dd2ed408cbb662fd84adb7803035c9c61e9a.tar.gz bcm5719-llvm-0bf2dd2ed408cbb662fd84adb7803035c9c61e9a.zip |
First half of jump scope checking for indirect goto.
llvm-svn: 69498
Diffstat (limited to 'clang')
-rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 28 | ||||
-rw-r--r-- | clang/test/Sema/scope-check.c | 26 |
3 files changed, 49 insertions, 7 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 8330a02b2a6..9b9b2a1d394 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -834,6 +834,8 @@ def err_undeclared_label_use : Error<"use of undeclared label '%0'">; def err_goto_into_protected_scope : Error<"illegal goto into protected scope">; def err_switch_into_protected_scope : Error< "illegal switch case into protected scope">; +def err_indirect_goto_in_protected_scope : Error< + "illegal indirect goto in protected scope, unknown effect on scopes">; def note_protected_by_vla_typedef : Note< "jump bypasses initialization of VLA typedef">; def note_protected_by_vla : Note< diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index ac974136343..2aaa1bc940c 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/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; } } diff --git a/clang/test/Sema/scope-check.c b/clang/test/Sema/scope-check.c index 98662be621b..4605e02b880 100644 --- a/clang/test/Sema/scope-check.c +++ b/clang/test/Sema/scope-check.c @@ -83,6 +83,7 @@ int test8(int x) { goto L6; 4; }); L6:; // ok. + if (x) goto L6; // ok } { @@ -113,6 +114,13 @@ int test8(int x) { //int A[({ L11: 4; })]; } + { + goto L12; + + int y = 4; // fixme-warn: skips initializer. + L12: + ; + } // Statement expressions 2. goto L1; // expected-error {{illegal goto into protected scope}} @@ -121,3 +129,21 @@ int test8(int x) { L1: 42; }); } + +void test9(int n, void *P) { + int Y; + int Z = 4; + goto *P; // ok. + +L2: ; + int a[n]; // expected-note {{jump bypasses initialization of variable length array}} + +L3: + goto *P; // expected-error {{illegal indirect goto in protected scope, unknown effect on scopes}} + + void *Ptrs[] = { + &&L2, + &&L3 // FIXME: Not Ok. + }; +} + |