[cfe-commits] [PATCH] Don't warn on fall-through from unreachable code.

Alexander Kornienko alexfh at google.com
Mon Jan 28 11:55:11 PST 2013


  Reverted to the original approach + fixed one more bug pointed out by rsmith.

Hi rsmith, doug.gregor,

http://llvm-reviews.chandlerc.com/D330

CHANGE SINCE LAST DIFF
  http://llvm-reviews.chandlerc.com/D330?vs=790&id=796#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,31 @@
       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.
+        ReachableBlocks.insert(*Cfg->rbegin());
+        BlockQueue.push_back(*Cfg->rbegin());
+        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.count(*I)) {
+              ReachableBlocks.insert(*I);
+              BlockQueue.push_back(*I);
+            }
+          }
+        }
+      }
+
       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 +745,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 +834,7 @@
     bool FoundSwitchStatements;
     AttrStmts FallthroughStmts;
     Sema &S;
+    llvm::SmallPtrSet<const CFGBlock *, 16> ReachableBlocks;
   };
 }
 
@@ -847,16 +866,15 @@
   if (!Cfg)
     return;
 
-  int AnnotatedCnt;
-
   for (CFG::reverse_iterator I = Cfg->rbegin(), E = Cfg->rend(); I != E; ++I) {
     const CFGBlock *B = *I;
     const Stmt *Label = B->getLabel();
 
     if (!Label || !isa<SwitchCase>(Label))
       continue;
 
-    if (!FM.checkFallThroughIntoBlock(*B, AnnotatedCnt))
+    int 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}}
     }
@@ -39,14 +39,13 @@
       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 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.6.patch
Type: text/x-patch
Size: 4141 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130128/f82097a7/attachment.bin>


More information about the cfe-commits mailing list