summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-08-02 23:33:14 +0000
committerJohn McCall <rjmccall@apple.com>2010-08-02 23:33:14 +0000
commit4a33fa95c014174b03bd56b357d05861e6379a37 (patch)
treeca2da287b12c419b0df6001ca119f5d49dc63f6f /clang/lib
parent460a356bf6c795618f6c7f82abdb9ec54bff6817 (diff)
downloadbcm5719-llvm-4a33fa95c014174b03bd56b357d05861e6379a37.tar.gz
bcm5719-llvm-4a33fa95c014174b03bd56b357d05861e6379a37.zip
Labels (and case statement) don't create independent scope parents for the
purposes of the jump checker. Also extend Ted's iteration fix to labels. Fixes PR7789. llvm-svn: 110082
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Sema/JumpDiagnostics.cpp34
1 files changed, 18 insertions, 16 deletions
diff --git a/clang/lib/Sema/JumpDiagnostics.cpp b/clang/lib/Sema/JumpDiagnostics.cpp
index f696d6acbf9..866a358e13a 100644
--- a/clang/lib/Sema/JumpDiagnostics.cpp
+++ b/clang/lib/Sema/JumpDiagnostics.cpp
@@ -180,22 +180,6 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned ParentScope) {
// If we found a label, remember that it is in ParentScope scope.
switch (S->getStmtClass()) {
- case Stmt::LabelStmtClass:
- case Stmt::DefaultStmtClass:
- LabelAndGotoScopes[S] = ParentScope;
- break;
- case Stmt::CaseStmtClass: {
- // Specially handle CaseStmts since they can nest each other in the
- // AST and blow out the stack when we walk them.
- CaseStmt *CS = cast<CaseStmt>(S);
- do {
- LabelAndGotoScopes[CS] = ParentScope;
- S = CS; // 'CS' is the new current statement (if it isn't already).
- CS = dyn_cast<CaseStmt>(CS->getSubStmt());
- } while (CS);
- break;
- }
-
case Stmt::AddrLabelExprClass:
IndirectJumpTargets.push_back(cast<AddrLabelExpr>(S)->getLabel());
break;
@@ -235,6 +219,24 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned ParentScope) {
Stmt *SubStmt = *CI;
if (SubStmt == 0) continue;
+ // Cases, labels, and defaults aren't "scope parents". It's also
+ // important to handle these iteratively instead of recursively in
+ // order to avoid blowing out the stack.
+ while (true) {
+ Stmt *Next;
+ if (isa<CaseStmt>(SubStmt))
+ Next = cast<CaseStmt>(SubStmt)->getSubStmt();
+ else if (isa<DefaultStmt>(SubStmt))
+ Next = cast<DefaultStmt>(SubStmt)->getSubStmt();
+ else if (isa<LabelStmt>(SubStmt))
+ Next = cast<LabelStmt>(SubStmt)->getSubStmt();
+ else
+ break;
+
+ LabelAndGotoScopes[SubStmt] = ParentScope;
+ SubStmt = Next;
+ }
+
// If this is a declstmt with a VLA definition, it defines a scope from here
// to the end of the containing context.
if (DeclStmt *DS = dyn_cast<DeclStmt>(SubStmt)) {
OpenPOWER on IntegriCloud