diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/Stmt.cpp | 16 | ||||
-rw-r--r-- | lib/Analysis/CFG.cpp | 8 |
2 files changed, 18 insertions, 6 deletions
diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp index 9e4be94011..e7b87e4db6 100644 --- a/lib/AST/Stmt.cpp +++ b/lib/AST/Stmt.cpp @@ -97,6 +97,22 @@ Stmt *Stmt::IgnoreImplicit() { return s; } +/// \brief Strip off all label-like statements. +/// +/// This will strip off label statements, case statements, and default +/// statements recursively. +const Stmt *Stmt::stripLabelLikeStatements() const { + const Stmt *S = this; + while (true) { + if (const LabelStmt *LS = dyn_cast<LabelStmt>(S)) + S = LS->getSubStmt(); + else if (const SwitchCase *SC = dyn_cast<SwitchCase>(S)) + S = SC->getSubStmt(); + else + return S; + } +} + namespace { struct good {}; struct bad {}; diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp index 393feffdad..d385420a56 100644 --- a/lib/Analysis/CFG.cpp +++ b/lib/Analysis/CFG.cpp @@ -723,9 +723,7 @@ void CFGBuilder::addLocalScopeForStmt(Stmt *S) { if (CompoundStmt *CS = dyn_cast<CompoundStmt>(S)) { for (CompoundStmt::body_iterator BI = CS->body_begin(), BE = CS->body_end() ; BI != BE; ++BI) { - Stmt *SI = *BI; - if (LabelStmt *LS = dyn_cast<LabelStmt>(SI)) - SI = LS->getSubStmt(); + Stmt *SI = (*BI)->stripLabelLikeStatements(); if (DeclStmt *DS = dyn_cast<DeclStmt>(SI)) Scope = addLocalScopeForDeclStmt(DS, Scope); } @@ -734,9 +732,7 @@ void CFGBuilder::addLocalScopeForStmt(Stmt *S) { // For any other statement scope will be implicit and as such will be // interesting only for DeclStmt. - if (LabelStmt *LS = dyn_cast<LabelStmt>(S)) - S = LS->getSubStmt(); - if (DeclStmt *DS = dyn_cast<DeclStmt>(S)) + if (DeclStmt *DS = dyn_cast<DeclStmt>(S->stripLabelLikeStatements())) addLocalScopeForDeclStmt(DS); } |