nickdesaulniers updated this revision to Diff 306787.
nickdesaulniers added a comment.

- check the successor's terminator


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D91895/new/

https://reviews.llvm.org/D91895

Files:
  clang/lib/Sema/AnalysisBasedWarnings.cpp
  clang/test/SemaCXX/switch-implicit-fallthrough-blocks.cpp
  clang/test/SemaCXX/switch-implicit-fallthrough.cpp

Index: clang/test/SemaCXX/switch-implicit-fallthrough.cpp
===================================================================
--- clang/test/SemaCXX/switch-implicit-fallthrough.cpp
+++ clang/test/SemaCXX/switch-implicit-fallthrough.cpp
@@ -151,23 +151,23 @@
 #define MY_CASE2(X, Y, U, V) case X: Y; case U: V
 
 int fallthrough_macro1(int n) {
-  MY_SWITCH(n, 13, n *= 2, 14, break)  // expected-warning{{unannotated fall-through between switch labels}}
+  MY_SWITCH(n, 13, n *= 2, 14, break)
 
   switch (n + 1) {
     MY_CASE(33, n += 2);
-    MY_CASE(44, break);  // expected-warning{{unannotated fall-through between switch labels}}
-    MY_CASE(55, n += 3);
+    MY_CASE(44, n += 3);  // expected-warning{{unannotated fall-through between switch labels}}
+    MY_CASE(55, break);
   }
 
   switch (n + 3) {
     MY_CASE(333, return 333);
-    MY_CASE2(444, n += 44, 4444, break);  // expected-warning{{unannotated fall-through between switch labels}}
+    MY_CASE2(444, n += 44, 4444, break);
     MY_CASE(555, n += 33);
   }
 
-  MY_SWITCH2(n + 4, MY_CASE(17, n *= 3), MY_CASE(19, break))  // expected-warning{{unannotated fall-through between switch labels}}
+  MY_SWITCH2(n + 4, MY_CASE(17, n *= 3), MY_CASE(19, break))
 
-  MY_SWITCH2(n + 5, MY_CASE(21, break), MY_CASE2(23, n *= 7, 25, break))  // expected-warning{{unannotated fall-through between switch labels}}
+  MY_SWITCH2(n + 5, MY_CASE(21, break), MY_CASE2(23, n *= 7, 25, break))
 
   return n;
 }
@@ -237,9 +237,15 @@
           [[clang::fallthrough]]; // no diagnostics
         case 1:
           x++;
+        case 2: // no diagnostics
+          break;
+        case 3:
+          x++;
         default: // \
             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}}
+          x++;
           break;
       }
     }
@@ -257,9 +263,15 @@
       [[clang::fallthrough]]; // no diagnostics
     case 1:
       x++;
+    case 2: // no diagnostics
+      break;
+    case 3:
+      x++;
     default: // \
         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}}
+      x++;
       break;
     }
   };
Index: clang/test/SemaCXX/switch-implicit-fallthrough-blocks.cpp
===================================================================
--- clang/test/SemaCXX/switch-implicit-fallthrough-blocks.cpp
+++ clang/test/SemaCXX/switch-implicit-fallthrough-blocks.cpp
@@ -7,11 +7,17 @@
     case 0:
       x++;
       [[clang::fallthrough]]; // no diagnostics
+    case 2:
+      x++;
+    case 3: // no diagnostics
+      break;
     case 1:
       x++;
     default: // \
         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}}
+      x++;
       break;
     }
   };
Index: clang/lib/Sema/AnalysisBasedWarnings.cpp
===================================================================
--- clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -1149,6 +1149,15 @@
           continue; // Fallthrough annotation, good.
         }
 
+        // If next statment in P's successor is a break with no other
+        // statements, no issue.
+        if (P->succ_size() == 1) {
+          const CFGBlock::AdjacentBlock &Succ = *P->succ_begin();
+          const Stmt *Term = Succ->getTerminatorStmt();
+          if (Succ->size() == 0 && Term && isa<BreakStmt>(Term))
+            continue;
+        }
+
         if (!LastStmt) { // This block contains no executable statements.
           // Traverse its predecessors.
           std::copy(P->pred_begin(), P->pred_end(),
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to