Removed ReachableBlocksFilled. Hi rsmith, doug.gregor,
http://llvm-reviews.chandlerc.com/D330 CHANGE SINCE LAST DIFF http://llvm-reviews.chandlerc.com/D330?vs=767&id=769#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 @@ -702,12 +702,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 (ReachableBlocks.empty()) { + // Searching for all blocks reachable from the entry point. + 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)); + } + } + 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 +739,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 +828,7 @@ bool FoundSwitchStatements; AttrStmts FallthroughStmts; Sema &S; + llvm::SmallPtrSet<const CFGBlock *, 16> ReachableBlocks; }; } @@ -856,7 +869,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
Index: lib/Sema/AnalysisBasedWarnings.cpp =================================================================== --- lib/Sema/AnalysisBasedWarnings.cpp +++ lib/Sema/AnalysisBasedWarnings.cpp @@ -702,12 +702,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 (ReachableBlocks.empty()) { + // Searching for all blocks reachable from the entry point. + 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)); + } + } + 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 +739,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 +828,7 @@ bool FoundSwitchStatements; AttrStmts FallthroughStmts; Sema &S; + llvm::SmallPtrSet<const CFGBlock *, 16> ReachableBlocks; }; } @@ -856,7 +869,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
_______________________________________________ cfe-commits mailing list cfe-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits