diff options
author | Alexander Kornienko <alexfh@google.com> | 2013-02-07 02:17:19 +0000 |
---|---|---|
committer | Alexander Kornienko <alexfh@google.com> | 2013-02-07 02:17:19 +0000 |
commit | 878d0ad2c9d83ee6485fd16e21c5082acc63a890 (patch) | |
tree | f0cd536477945ab29c3e14de06c463ee476afdf0 /lib/Sema | |
parent | cd3b036dbdd29b0ddcaa12b5cce69b647b2ac5ba (diff) | |
download | clang-878d0ad2c9d83ee6485fd16e21c5082acc63a890.tar.gz |
-Wimplicit-fallthrough: fixed two cases where "fallthrough annotation in unreachable code" was issued incorrectly.
Summary:
-Wimplicit-fallthrough: fixed two cases where "fallthrough annotation in unreachable code" was issued incorrectly:
1. In actual unreachable code, but not immediately on a fall-through execution
path "fallthrough annotation does not directly precede switch label" is better;
2. After default: in a switch with covered enum cases. Actually, these shouldn't
be treated as unreachable code for our purpose.
Reviewers: rsmith
Reviewed By: rsmith
CC: cfe-commits
Differential Revision: http://llvm-reviews.chandlerc.com/D374
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@174575 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/AnalysisBasedWarnings.cpp | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp index 5443edb191..c2b54d0280 100644 --- a/lib/Sema/AnalysisBasedWarnings.cpp +++ b/lib/Sema/AnalysisBasedWarnings.cpp @@ -708,6 +708,17 @@ namespace { ReachableBlocks.insert(&Cfg->getEntry()); BlockQueue.push_back(&Cfg->getEntry()); + // Mark all case blocks reachable to avoid problems with switching on + // constants, covered enums, etc. + // These blocks can contain fall-through annotations, and we don't want to + // issue a warn_fallthrough_attr_unreachable for them. + for (CFG::iterator I = Cfg->begin(), E = Cfg->end(); I != E; ++I) { + const CFGBlock *B = *I; + const Stmt *L = B->getLabel(); + if (L && isa<SwitchCase>(L) && ReachableBlocks.insert(B)) + BlockQueue.push_back(B); + } + while (!BlockQueue.empty()) { const CFGBlock *P = BlockQueue.front(); BlockQueue.pop_front(); @@ -747,14 +758,16 @@ namespace { continue; // Case label is preceded with a normal label, good. if (!ReachableBlocks.count(P)) { - for (CFGBlock::const_iterator ElIt = P->begin(), ElEnd = P->end(); - ElIt != ElEnd; ++ElIt) { - if (const CFGStmt *CS = ElIt->getAs<CFGStmt>()){ + for (CFGBlock::const_reverse_iterator ElemIt = P->rbegin(), + ElemEnd = P->rend(); + ElemIt != ElemEnd; ++ElemIt) { + if (const CFGStmt *CS = ElemIt->getAs<CFGStmt>()) { if (const AttributedStmt *AS = asFallThroughAttr(CS->getStmt())) { S.Diag(AS->getLocStart(), diag::warn_fallthrough_attr_unreachable); markFallthroughVisited(AS); ++AnnotatedCnt; + break; } // Don't care about other unreachable statements. } |