r173889 - Don't warn on fall-through from unreachable code.
Alexander Kornienko
alexfh at google.com
Tue Jan 29 19:49:44 PST 2013
Author: alexfh
Date: Tue Jan 29 21:49:44 2013
New Revision: 173889
URL: http://llvm.org/viewvc/llvm-project?rev=173889&view=rev
Log:
Don't warn on fall-through from unreachable code.
Summary:
A motivating example:
class ClassWithDtor {
public:
~ClassWithDtor() {}
};
void fallthrough3(int n) {
switch (n) {
case 2:
do {
ClassWithDtor temp;
return;
} while (0); // This generates a chain of unreachable CFG blocks.
case 3:
break;
}
}
Reviewers: rsmith, doug.gregor, alexfh
Reviewed By: alexfh
CC: cfe-commits
Differential Revision: http://llvm-reviews.chandlerc.com/D330
Modified:
cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp
cfe/trunk/test/SemaCXX/switch-implicit-fallthrough.cpp
Modified: cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp?rev=173889&r1=173888&r2=173889&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp (original)
+++ cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp Tue Jan 29 21:49:44 2013
@@ -702,7 +702,27 @@ namespace {
return FallthroughStmts;
}
+ void fillReachableBlocks(CFG *Cfg) {
+ assert(ReachableBlocks.empty() && "ReachableBlocks already filled");
+ std::deque<const CFGBlock *> BlockQueue;
+
+ ReachableBlocks.insert(&Cfg->getEntry());
+ BlockQueue.push_back(&Cfg->getEntry());
+ while (!BlockQueue.empty()) {
+ const CFGBlock *P = BlockQueue.front();
+ BlockQueue.pop_front();
+ for (CFGBlock::const_succ_iterator I = P->succ_begin(),
+ E = P->succ_end();
+ I != E; ++I) {
+ if (ReachableBlocks.insert(*I))
+ BlockQueue.push_back(*I);
+ }
+ }
+ }
+
bool checkFallThroughIntoBlock(const CFGBlock &B, int &AnnotatedCnt) {
+ assert(!ReachableBlocks.empty() && "ReachableBlocks empty");
+
int UnannotatedCnt = 0;
AnnotatedCnt = 0;
@@ -726,8 +746,7 @@ namespace {
if (L && L->getSubStmt() == B.getLabel() && P->begin() == P->end())
continue; // Case label is preceded with a normal label, good.
- if (P->pred_begin() == P->pred_end()) { // The block is unreachable.
- // This only catches trivially unreachable blocks.
+ if (!ReachableBlocks.count(P)) {
for (CFGBlock::const_iterator ElIt = P->begin(), ElEnd = P->end();
ElIt != ElEnd; ++ElIt) {
if (const CFGStmt *CS = ElIt->getAs<CFGStmt>()){
@@ -816,6 +835,7 @@ namespace {
bool FoundSwitchStatements;
AttrStmts FallthroughStmts;
Sema &S;
+ llvm::SmallPtrSet<const CFGBlock *, 16> ReachableBlocks;
};
}
@@ -847,7 +867,7 @@ static void DiagnoseSwitchLabelsFallthro
if (!Cfg)
return;
- int AnnotatedCnt;
+ FM.fillReachableBlocks(Cfg);
for (CFG::reverse_iterator I = Cfg->rbegin(), E = Cfg->rend(); I != E; ++I) {
const CFGBlock *B = *I;
@@ -856,6 +876,8 @@ static void DiagnoseSwitchLabelsFallthro
if (!Label || !isa<SwitchCase>(Label))
continue;
+ int AnnotatedCnt;
+
if (!FM.checkFallThroughIntoBlock(*B, AnnotatedCnt))
continue;
Modified: cfe/trunk/test/SemaCXX/switch-implicit-fallthrough.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/switch-implicit-fallthrough.cpp?rev=173889&r1=173888&r2=173889&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/switch-implicit-fallthrough.cpp (original)
+++ cfe/trunk/test/SemaCXX/switch-implicit-fallthrough.cpp Tue Jan 29 21:49:44 2013
@@ -10,7 +10,7 @@ int fallthrough(int n) {
} else if (n - 3) {
n = 102;
}
- case -1: // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}}
+ case -1: // no warning here, ignore fall-through from unreachable code
;
case 0: {// expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}}
}
@@ -39,14 +39,13 @@ int fallthrough(int n) {
break;
}
switch (n / 15) {
-label_case_70:
- case 70:
+label_default:
+ default:
n += 333;
+ if (n % 10)
+ goto label_default;
break;
- case 71:
- n += 334;
- goto label_case_70;
- case 72:
+ case 70:
n += 335;
break;
}
@@ -130,6 +129,22 @@ void fallthrough2(int n) {
}
}
+void fallthrough3(int n) {
+ switch (n) {
+ case 1:
+ do {
+ return;
+ } while (0);
+ case 2:
+ do {
+ ClassWithDtor temp;
+ return;
+ } while (0);
+ case 3:
+ break;
+ }
+}
+
#define MY_SWITCH(X, Y, Z, U, V) switch (X) { case Y: Z; case U: V; }
#define MY_SWITCH2(X, Y, Z) switch (X) { Y; Z; }
#define MY_CASE(X, Y) case X: Y
More information about the cfe-commits
mailing list