diff options
Diffstat (limited to 'lib/Sema/JumpDiagnostics.cpp')
-rw-r--r-- | lib/Sema/JumpDiagnostics.cpp | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/lib/Sema/JumpDiagnostics.cpp b/lib/Sema/JumpDiagnostics.cpp index 3431ac611886..b23f615af7b7 100644 --- a/lib/Sema/JumpDiagnostics.cpp +++ b/lib/Sema/JumpDiagnostics.cpp @@ -12,11 +12,12 @@ // //===----------------------------------------------------------------------===// -#include "llvm/ADT/BitVector.h" -#include "Sema.h" +#include "clang/Sema/SemaInternal.h" +#include "clang/AST/DeclCXX.h" #include "clang/AST/Expr.h" #include "clang/AST/StmtObjC.h" #include "clang/AST/StmtCXX.h" +#include "llvm/ADT/BitVector.h" using namespace clang; namespace { @@ -180,12 +181,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: - case Stmt::CaseStmtClass: - LabelAndGotoScopes[S] = ParentScope; - break; - case Stmt::AddrLabelExprClass: IndirectJumpTargets.push_back(cast<AddrLabelExpr>(S)->getLabel()); break; @@ -225,6 +220,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)) { |