hazohelet created this revision.
hazohelet added reviewers: tbaeder, aaron.ballman, cjdb.
Herald added a reviewer: NoQ.
Herald added a project: All.
hazohelet requested review of this revision.
Herald added a project: clang.

This patch checks whether `-Wunreachable-code-fallthrough` is enabled when 
clang encounters unreachable fallthrough attributes and, if so, suppresses 
`code will never be executed` warning to avoid duplicate warnings.
This fixes https://github.com/llvm/llvm-project/issues/60416


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D145842

Files:
  clang/include/clang/Analysis/Analyses/ReachableCode.h
  clang/lib/Analysis/ReachableCode.cpp
  clang/lib/Sema/AnalysisBasedWarnings.cpp
  clang/test/Sema/warn-unreachable-fallthrough.c

Index: clang/test/Sema/warn-unreachable-fallthrough.c
===================================================================
--- /dev/null
+++ clang/test/Sema/warn-unreachable-fallthrough.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c2x -Wunreachable-code-fallthrough %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c2x -Wunreachable-code %s
+// RUN: %clang_cc1 -fsyntax-only -verify=code -std=c2x -Wunreachable-code -Wno-unreachable-code-fallthrough %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c2x -Wno-unreachable-code -Wunreachable-code-fallthrough %s
+
+int n;
+void f(void){
+     switch (n){
+         [[fallthrough]]; // expected-warning{{fallthrough annotation in unreachable code}}
+                          // code-warning@-1{{never be executed}}
+         case 1:;
+     }
+}
Index: clang/lib/Sema/AnalysisBasedWarnings.cpp
===================================================================
--- clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -123,7 +123,8 @@
     return;
 
   UnreachableCodeHandler UC(S);
-  reachable_code::FindUnreachableCode(AC, S.getPreprocessor(), UC);
+  reachable_code::FindUnreachableCode(AC, S.getPreprocessor(),
+                                      S.getDiagnostics(), UC);
 }
 
 namespace {
Index: clang/lib/Analysis/ReachableCode.cpp
===================================================================
--- clang/lib/Analysis/ReachableCode.cpp
+++ clang/lib/Analysis/ReachableCode.cpp
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Analysis/Analyses/ReachableCode.h"
+#include "clang/AST/Attr.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
@@ -22,6 +23,7 @@
 #include "clang/Basic/Builtins.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Lex/Preprocessor.h"
+#include "clang/Sema/SemaDiagnostic.h"
 #include "llvm/ADT/BitVector.h"
 #include "llvm/ADT/SmallVector.h"
 #include <optional>
@@ -408,15 +410,15 @@
       PP(PP), C(C) {}
 
     void enqueue(const CFGBlock *block);
-    unsigned scanBackwards(const CFGBlock *Start,
-    clang::reachable_code::Callback &CB);
+    unsigned scanBackwards(const CFGBlock *Start, const DiagnosticsEngine &Diag,
+                           clang::reachable_code::Callback &CB);
 
     bool isDeadCodeRoot(const CFGBlock *Block);
 
     const Stmt *findDeadCode(const CFGBlock *Block);
 
-    void reportDeadCode(const CFGBlock *B,
-                        const Stmt *S,
+    void reportDeadCode(const CFGBlock *B, const Stmt *S,
+                        const DiagnosticsEngine &Diag,
                         clang::reachable_code::Callback &CB);
   };
 }
@@ -488,6 +490,7 @@
 }
 
 unsigned DeadCodeScan::scanBackwards(const clang::CFGBlock *Start,
+                                     const DiagnosticsEngine &Diag,
                                      clang::reachable_code::Callback &CB) {
 
   unsigned count = 0;
@@ -521,7 +524,7 @@
     }
 
     if (isDeadCodeRoot(Block)) {
-      reportDeadCode(Block, S, CB);
+      reportDeadCode(Block, S, Diag, CB);
       count += scanMaybeReachableFromBlock(Block, PP, Reachable);
     }
     else {
@@ -540,7 +543,7 @@
       const CFGBlock *Block = I.first;
       if (Reachable[Block->getBlockID()])
         continue;
-      reportDeadCode(Block, I.second, CB);
+      reportDeadCode(Block, I.second, Diag, CB);
       count += scanMaybeReachableFromBlock(Block, PP, Reachable);
     }
   }
@@ -613,8 +616,8 @@
   return S->getBeginLoc();
 }
 
-void DeadCodeScan::reportDeadCode(const CFGBlock *B,
-                                  const Stmt *S,
+void DeadCodeScan::reportDeadCode(const CFGBlock *B, const Stmt *S,
+                                  const DiagnosticsEngine &Diag,
                                   clang::reachable_code::Callback &CB) {
   // Classify the unreachable code found, or suppress it in some cases.
   reachable_code::UnreachableKind UK = reachable_code::UK_Other;
@@ -663,6 +666,16 @@
     }
   }
 
+  // If S is `[[fallthrough]];` and `-Wunreachable-code-fallthrough` is enabled,
+  // suppress `code will never be executed` warning to avoid generating
+  // diagnostic twice
+  const AttributedStmt *AS = dyn_cast<AttributedStmt>(S);
+  if (AS && hasSpecificAttr<FallThroughAttr>(AS->getAttrs()) &&
+      !Diag.isIgnored(diag::warn_unreachable_fallthrough_attr,
+                      SourceLocation())) {
+    return;
+  }
+
   SourceRange R1, R2;
   SourceLocation Loc = GetUnreachableLoc(S, R1, R2);
   CB.HandleUnreachable(UK, Loc, SilenceableCondVal, R1, R2);
@@ -682,7 +695,7 @@
 }
 
 void FindUnreachableCode(AnalysisDeclContext &AC, Preprocessor &PP,
-                         Callback &CB) {
+                         const DiagnosticsEngine &Diag, Callback &CB) {
 
   CFG *cfg = AC.getCFG();
   if (!cfg)
@@ -713,11 +726,10 @@
       continue;
 
     DeadCodeScan DS(reachable, PP, AC.getASTContext());
-    numReachable += DS.scanBackwards(block, CB);
+    numReachable += DS.scanBackwards(block, Diag, CB);
 
     if (numReachable == cfg->getNumBlockIDs())
       return;
   }
 }
-
 }} // end namespace clang::reachable_code
Index: clang/include/clang/Analysis/Analyses/ReachableCode.h
===================================================================
--- clang/include/clang/Analysis/Analyses/ReachableCode.h
+++ clang/include/clang/Analysis/Analyses/ReachableCode.h
@@ -13,6 +13,7 @@
 #ifndef LLVM_CLANG_ANALYSIS_ANALYSES_REACHABLECODE_H
 #define LLVM_CLANG_ANALYSIS_ANALYSES_REACHABLECODE_H
 
+#include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/SourceLocation.h"
 
 //===----------------------------------------------------------------------===//
@@ -61,8 +62,7 @@
                                 llvm::BitVector &Reachable);
 
 void FindUnreachableCode(AnalysisDeclContext &AC, Preprocessor &PP,
-                         Callback &CB);
-
+                         const DiagnosticsEngine &Diag, Callback &CB);
 }} // end namespace clang::reachable_code
 
 #endif
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to