diff options
author | Aaron Ballman <aaron@aaronballman.com> | 2025-04-23 06:55:10 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-04-23 06:55:10 -0400 |
commit | 71ce9e26aec00e4af27a69ccfab8ca1773ed7018 (patch) | |
tree | 579724cce4e4fafe9d1c6fc1647f79c235577f14 /clang/lib/Sema/AnalysisBasedWarnings.cpp | |
parent | 2a9f77f6bd48d757b2d45aadcb6cf76ef4b4ef32 (diff) | |
download | llvm-71ce9e26aec00e4af27a69ccfab8ca1773ed7018.zip llvm-71ce9e26aec00e4af27a69ccfab8ca1773ed7018.tar.gz llvm-71ce9e26aec00e4af27a69ccfab8ca1773ed7018.tar.bz2 |
Control analysis-based diagnostics with #pragma (#136323)
Previously, analysis-based diagnostics (like -Wconsumed) had to be
enabled at file scope in order to be run at the end of each function
body. This meant that they did not respect #pragma clang diagnostic
enabling or disabling the diagnostic.
Now, these pragmas can control the diagnostic emission.
Fixes #42199
Diffstat (limited to 'clang/lib/Sema/AnalysisBasedWarnings.cpp')
-rw-r--r-- | clang/lib/Sema/AnalysisBasedWarnings.cpp | 43 |
1 files changed, 31 insertions, 12 deletions
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp index 32c7ee9..3d8eaf0 100644 --- a/clang/lib/Sema/AnalysisBasedWarnings.cpp +++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp @@ -2492,9 +2492,11 @@ public: CalledOnceInterProceduralData CalledOnceData; }; -static unsigned isEnabled(DiagnosticsEngine &D, unsigned diag) { - return (unsigned)!D.isIgnored(diag, SourceLocation()); -} +template <typename... Ts> +static bool areAnyEnabled(DiagnosticsEngine &D, SourceLocation Loc, + Ts... Diags) { + return (!D.isIgnored(Diags, Loc) || ...); +}; sema::AnalysisBasedWarnings::AnalysisBasedWarnings(Sema &s) : S(s), IPData(std::make_unique<InterProceduralData>()), @@ -2503,23 +2505,37 @@ sema::AnalysisBasedWarnings::AnalysisBasedWarnings(Sema &s) NumUninitAnalysisVariables(0), MaxUninitAnalysisVariablesPerFunction(0), NumUninitAnalysisBlockVisits(0), MaxUninitAnalysisBlockVisitsPerFunction(0) { +} + +// We need this here for unique_ptr with forward declared class. +sema::AnalysisBasedWarnings::~AnalysisBasedWarnings() = default; +sema::AnalysisBasedWarnings::Policy +sema::AnalysisBasedWarnings::getPolicyInEffectAt(SourceLocation Loc) { using namespace diag; DiagnosticsEngine &D = S.getDiagnostics(); + Policy P; - DefaultPolicy.enableCheckUnreachable = - isEnabled(D, warn_unreachable) || isEnabled(D, warn_unreachable_break) || - isEnabled(D, warn_unreachable_return) || - isEnabled(D, warn_unreachable_loop_increment); + // Note: The enabled checks should be kept in sync with the switch in + // SemaPPCallbacks::PragmaDiagnostic(). + P.enableCheckUnreachable = + PolicyOverrides.enableCheckUnreachable || + areAnyEnabled(D, Loc, warn_unreachable, warn_unreachable_break, + warn_unreachable_return, warn_unreachable_loop_increment); - DefaultPolicy.enableThreadSafetyAnalysis = isEnabled(D, warn_double_lock); + P.enableThreadSafetyAnalysis = PolicyOverrides.enableThreadSafetyAnalysis || + areAnyEnabled(D, Loc, warn_double_lock); - DefaultPolicy.enableConsumedAnalysis = - isEnabled(D, warn_use_in_invalid_state); + P.enableConsumedAnalysis = PolicyOverrides.enableConsumedAnalysis || + areAnyEnabled(D, Loc, warn_use_in_invalid_state); + return P; } -// We need this here for unique_ptr with forward declared class. -sema::AnalysisBasedWarnings::~AnalysisBasedWarnings() = default; +void sema::AnalysisBasedWarnings::clearOverrides() { + PolicyOverrides.enableCheckUnreachable = false; + PolicyOverrides.enableConsumedAnalysis = false; + PolicyOverrides.enableThreadSafetyAnalysis = false; +} static void flushDiagnostics(Sema &S, const sema::FunctionScopeInfo *fscope) { for (const auto &D : fscope->PossiblyUnreachableDiags) @@ -2870,6 +2886,9 @@ void clang::sema::AnalysisBasedWarnings::IssueWarnings( AC.getCFG(); } + // Clear any of our policy overrides. + clearOverrides(); + // Collect statistics about the CFG if it was built. if (S.CollectStats && AC.isCFGBuilt()) { ++NumFunctionsAnalyzed; |