diff options
| author | John McCall <rjmccall@apple.com> | 2010-08-02 23:33:14 +0000 |
|---|---|---|
| committer | John McCall <rjmccall@apple.com> | 2010-08-02 23:33:14 +0000 |
| commit | 4a33fa95c014174b03bd56b357d05861e6379a37 (patch) | |
| tree | ca2da287b12c419b0df6001ca119f5d49dc63f6f /clang/lib | |
| parent | 460a356bf6c795618f6c7f82abdb9ec54bff6817 (diff) | |
| download | bcm5719-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.cpp | 34 |
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)) { |

