aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2011-09-10 00:02:34 +0000
committerChandler Carruth <chandlerc@gmail.com>2011-09-10 00:02:34 +0000
commita1364be341550d71dff27dd8de0c6872ba6c707e (patch)
treee52c54751be195a46cc32717ecb006747542df63 /lib
parent35120c628595ecd05f9e82faa6a210837b48b236 (diff)
Extend the Stmt AST to make it easier to look through label, default,
and case statements. Use this to make the logic in the CFG builder more robust at finding the actual statements within a compound statement, even when there are many layers of labels obscuring it. Also extend the test cases for a large chunk of PR10063. Still more work to do here though. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@139437 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/Stmt.cpp16
-rw-r--r--lib/Analysis/CFG.cpp8
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);
}