diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Analysis/ReachableCode.cpp | 12 | ||||
-rw-r--r-- | clang/lib/Sema/AnalysisBasedWarnings.cpp | 16 |
2 files changed, 20 insertions, 8 deletions
diff --git a/clang/lib/Analysis/ReachableCode.cpp b/clang/lib/Analysis/ReachableCode.cpp index 5cc63bb..1bf0d9a 100644 --- a/clang/lib/Analysis/ReachableCode.cpp +++ b/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" @@ -629,6 +630,10 @@ void DeadCodeScan::reportDeadCode(const CFGBlock *B, UK = reachable_code::UK_Return; } + const auto *AS = dyn_cast<AttributedStmt>(S); + bool HasFallThroughAttr = + AS && hasSpecificAttr<FallThroughAttr>(AS->getAttrs()); + SourceRange SilenceableCondVal; if (UK == reachable_code::UK_Other) { @@ -645,8 +650,9 @@ void DeadCodeScan::reportDeadCode(const CFGBlock *B, R2 = Inc->getSourceRange(); } - CB.HandleUnreachable(reachable_code::UK_Loop_Increment, - Loc, SourceRange(), SourceRange(Loc, Loc), R2); + CB.HandleUnreachable(reachable_code::UK_Loop_Increment, Loc, + SourceRange(), SourceRange(Loc, Loc), R2, + HasFallThroughAttr); return; } @@ -665,7 +671,7 @@ void DeadCodeScan::reportDeadCode(const CFGBlock *B, SourceRange R1, R2; SourceLocation Loc = GetUnreachableLoc(S, R1, R2); - CB.HandleUnreachable(UK, Loc, SilenceableCondVal, R1, R2); + CB.HandleUnreachable(UK, Loc, SilenceableCondVal, R1, R2, HasFallThroughAttr); } //===----------------------------------------------------------------------===// diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp index 4367435..f5c48ed 100644 --- a/clang/lib/Sema/AnalysisBasedWarnings.cpp +++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp @@ -66,11 +66,17 @@ namespace { public: UnreachableCodeHandler(Sema &s) : S(s) {} - void HandleUnreachable(reachable_code::UnreachableKind UK, - SourceLocation L, - SourceRange SilenceableCondVal, - SourceRange R1, - SourceRange R2) override { + void HandleUnreachable(reachable_code::UnreachableKind UK, SourceLocation L, + SourceRange SilenceableCondVal, SourceRange R1, + SourceRange R2, bool HasFallThroughAttr) override { + // If the diagnosed code is `[[fallthrough]];` and + // `-Wunreachable-code-fallthrough` is enabled, suppress `code will never + // be executed` warning to avoid generating diagnostic twice + if (HasFallThroughAttr && + !S.getDiagnostics().isIgnored(diag::warn_unreachable_fallthrough_attr, + SourceLocation())) + return; + // Avoid reporting multiple unreachable code diagnostics that are // triggered by the same conditional value. if (PreviousSilenceableCondVal.isValid() && |