[cfe-commits] [PATCH] Don't warn on fall-through from unreachable code.
Alexander Kornienko
alexfh at google.com
Fri Jan 25 12:47:57 PST 2013
Updated after commiting D329
Hi rsmith, doug.gregor,
http://llvm-reviews.chandlerc.com/D330
CHANGE SINCE LAST DIFF
http://llvm-reviews.chandlerc.com/D330?vs=766&id=767#toc
Files:
lib/Sema/AnalysisBasedWarnings.cpp
test/SemaCXX/switch-implicit-fallthrough.cpp
Index: lib/Sema/AnalysisBasedWarnings.cpp
===================================================================
--- lib/Sema/AnalysisBasedWarnings.cpp
+++ lib/Sema/AnalysisBasedWarnings.cpp
@@ -685,7 +685,8 @@
public:
FallthroughMapper(Sema &S)
: FoundSwitchStatements(false),
- S(S) {
+ S(S),
+ ReachableBlocksFilled(false) {
}
bool foundSwitchStatements() const { return FoundSwitchStatements; }
@@ -702,12 +703,25 @@
return FallthroughStmts;
}
- bool checkFallThroughIntoBlock(const CFGBlock &B, int &AnnotatedCnt) {
+ bool checkFallThroughIntoBlock(const CFGBlock &B, int &AnnotatedCnt,
+ CFG *Cfg) {
+ std::deque<const CFGBlock *> BlockQueue;
+
+ if (!ReachableBlocksFilled) {
+ BlockQueue.push_back(*Cfg->rbegin());
+ while (!BlockQueue.empty()) {
+ const CFGBlock *P = BlockQueue.front();
+ BlockQueue.pop_front();
+ ReachableBlocks.insert(P);
+ std::copy(P->succ_begin(), P->succ_end(),
+ std::back_inserter(BlockQueue));
+ }
+ ReachableBlocksFilled = true;
+ }
+
int UnannotatedCnt = 0;
AnnotatedCnt = 0;
- std::deque<const CFGBlock*> BlockQueue;
-
std::copy(B.pred_begin(), B.pred_end(), std::back_inserter(BlockQueue));
while (!BlockQueue.empty()) {
@@ -726,8 +740,7 @@
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 +829,8 @@
bool FoundSwitchStatements;
AttrStmts FallthroughStmts;
Sema &S;
+ bool ReachableBlocksFilled;
+ llvm::SmallPtrSet<const CFGBlock *, 16> ReachableBlocks;
};
}
@@ -856,7 +871,7 @@
if (!Label || !isa<SwitchCase>(Label))
continue;
- if (!FM.checkFallThroughIntoBlock(*B, AnnotatedCnt))
+ if (!FM.checkFallThroughIntoBlock(*B, AnnotatedCnt, Cfg))
continue;
S.Diag(Label->getLocStart(),
Index: test/SemaCXX/switch-implicit-fallthrough.cpp
===================================================================
--- test/SemaCXX/switch-implicit-fallthrough.cpp
+++ test/SemaCXX/switch-implicit-fallthrough.cpp
@@ -10,7 +10,7 @@
} 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}}
}
@@ -130,6 +130,22 @@
}
}
+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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D330.2.patch
Type: text/x-patch
Size: 3624 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130125/e51ef332/attachment.bin>
More information about the cfe-commits
mailing list