summaryrefslogtreecommitdiff
path: root/lib/Sema
diff options
context:
space:
mode:
authorAlexander Kornienko <alexfh@google.com>2013-02-07 02:17:19 +0000
committerAlexander Kornienko <alexfh@google.com>2013-02-07 02:17:19 +0000
commit878d0ad2c9d83ee6485fd16e21c5082acc63a890 (patch)
treef0cd536477945ab29c3e14de06c463ee476afdf0 /lib/Sema
parentcd3b036dbdd29b0ddcaa12b5cce69b647b2ac5ba (diff)
downloadclang-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.cpp19
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.
}