https://github.com/joeedh updated https://github.com/llvm/llvm-project/pull/182912
>From 17490a6a4e39b0b3a2ddee48d2d2c5b0fd1257ae Mon Sep 17 00:00:00 2001 From: Joe Eagar <[email protected]> Date: Mon, 23 Feb 2026 10:09:50 -0800 Subject: [PATCH] [clangd] Pull suppression logic into common path, apply for driver diagnostics Rebase of https://reviews.llvm.org/D127844# Fixes #1142 --- clang-tools-extra/clangd/Diagnostics.cpp | 26 +++++++++++++------ clang-tools-extra/clangd/Diagnostics.h | 6 ++--- clang-tools-extra/clangd/ParsedAST.cpp | 5 ---- clang-tools-extra/clangd/Preamble.cpp | 5 ---- .../clangd/unittests/CompilerTests.cpp | 15 +++++++++++ .../clangd/unittests/DiagnosticsTests.cpp | 21 +++++++++++++++ 6 files changed, 57 insertions(+), 21 deletions(-) diff --git a/clang-tools-extra/clangd/Diagnostics.cpp b/clang-tools-extra/clangd/Diagnostics.cpp index e10960ca5850f..f04995740b129 100644 --- a/clang-tools-extra/clangd/Diagnostics.cpp +++ b/clang-tools-extra/clangd/Diagnostics.cpp @@ -9,6 +9,7 @@ #include "Diagnostics.h" #include "../clang-tidy/ClangTidyDiagnosticConsumer.h" #include "Compiler.h" +#include "Config.h" #include "Protocol.h" #include "SourceCode.h" #include "support/Logger.h" @@ -695,6 +696,19 @@ void StoreDiags::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, Info.getDiags()->getDiagnosticIDs()->isDefaultMappingAsError( Info.getID()); + if (!isNote(DiagLevel)) { + const Config &Cfg = Config::current(); + // Check if diagnostics is suppressed (possibly by user), before doing any + // adjustments. + if (Cfg.Diagnostics.SuppressAll || + isDiagnosticSuppressed(Info, Cfg.Diagnostics.Suppress, LangOpts)) { + DiagLevel = DiagnosticsEngine::Ignored; + } else if (Adjuster) { + // FIXME: Merge with feature modules. + DiagLevel = Adjuster(DiagLevel, Info); + } + } + if (Info.getLocation().isInvalid()) { // Handle diagnostics coming from command-line arguments. The source manager // is *not* available at this point, so we cannot use it. @@ -805,8 +819,7 @@ void StoreDiags::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, } if (Message.empty()) // either !SyntheticMessage, or we failed to make one. Info.FormatDiagnostic(Message); - LastDiag->Fixes.push_back( - Fix{std::string(Message), std::move(Edits), {}}); + LastDiag->Fixes.push_back(Fix{std::string(Message), std::move(Edits), {}}); return true; }; @@ -815,9 +828,6 @@ void StoreDiags::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, flushLastDiag(); LastDiag = Diag(); - // FIXME: Merge with feature modules. - if (Adjuster) - DiagLevel = Adjuster(DiagLevel, Info); FillDiagBase(*LastDiag); if (isExcluded(LastDiag->ID)) @@ -906,12 +916,12 @@ void StoreDiags::flushLastDiag() { bool isDiagnosticSuppressed(const clang::Diagnostic &Diag, const llvm::StringSet<> &Suppress, - const LangOptions &LangOpts) { + const std::optional<LangOptions> &LangOpts) { // Don't complain about header-only stuff in mainfiles if it's a header. // FIXME: would be cleaner to suppress in clang, once we decide whether the // behavior should be to silently-ignore or respect the pragma. - if (Diag.getID() == diag::pp_pragma_sysheader_in_main_file && - LangOpts.IsHeaderFile) + if (LangOpts && Diag.getID() == diag::pp_pragma_sysheader_in_main_file && + LangOpts->IsHeaderFile) return true; if (const char *CodePtr = getDiagnosticCode(Diag.getID())) { diff --git a/clang-tools-extra/clangd/Diagnostics.h b/clang-tools-extra/clangd/Diagnostics.h index c45d8dc3aa6ce..95f3da8bd0e47 100644 --- a/clang-tools-extra/clangd/Diagnostics.h +++ b/clang-tools-extra/clangd/Diagnostics.h @@ -173,8 +173,8 @@ class StoreDiags : public DiagnosticConsumer { std::vector<Diag> Output; std::optional<LangOptions> LangOpts; std::optional<Diag> LastDiag; - std::optional<FullSourceLoc> LastDiagLoc; // Valid only when LastDiag is set. - bool LastDiagOriginallyError = false; // Valid only when LastDiag is set. + std::optional<FullSourceLoc> LastDiagLoc; // Valid only when LastDiag is set. + bool LastDiagOriginallyError = false; // Valid only when LastDiag is set. SourceManager *OrigSrcMgr = nullptr; llvm::DenseSet<std::pair<unsigned, unsigned>> IncludedErrorLocations; @@ -183,7 +183,7 @@ class StoreDiags : public DiagnosticConsumer { /// Determine whether a (non-clang-tidy) diagnostic is suppressed by config. bool isDiagnosticSuppressed(const clang::Diagnostic &Diag, const llvm::StringSet<> &Suppressed, - const LangOptions &); + const std::optional<LangOptions> &); /// Take a user-specified diagnostic code, and convert it to a normalized form /// stored in the config and consumed by isDiagnosticsSuppressed. /// diff --git a/clang-tools-extra/clangd/ParsedAST.cpp b/clang-tools-extra/clangd/ParsedAST.cpp index c23b5d7a38d37..4e873f1257a17 100644 --- a/clang-tools-extra/clangd/ParsedAST.cpp +++ b/clang-tools-extra/clangd/ParsedAST.cpp @@ -585,11 +585,6 @@ ParsedAST::build(llvm::StringRef Filename, const ParseInputs &Inputs, ASTDiags.setLevelAdjuster([&](DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &Info) { - if (Cfg.Diagnostics.SuppressAll || - isDiagnosticSuppressed(Info, Cfg.Diagnostics.Suppress, - Clang->getLangOpts())) - return DiagnosticsEngine::Ignored; - auto It = OverriddenSeverity.find(Info.getID()); if (It != OverriddenSeverity.end()) DiagLevel = It->second; diff --git a/clang-tools-extra/clangd/Preamble.cpp b/clang-tools-extra/clangd/Preamble.cpp index cdda0208a96d6..f5e512793e98e 100644 --- a/clang-tools-extra/clangd/Preamble.cpp +++ b/clang-tools-extra/clangd/Preamble.cpp @@ -598,13 +598,8 @@ buildPreamble(PathRef FileName, CompilerInvocation CI, CompilerInstance::createDiagnostics(*VFS, CI.getDiagnosticOpts(), &PreambleDiagnostics, /*ShouldOwnClient=*/false); - const Config &Cfg = Config::current(); PreambleDiagnostics.setLevelAdjuster([&](DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &Info) { - if (Cfg.Diagnostics.SuppressAll || - isDiagnosticSuppressed(Info, Cfg.Diagnostics.Suppress, - CI.getLangOpts())) - return DiagnosticsEngine::Ignored; switch (Info.getID()) { case diag::warn_no_newline_eof: // If the preamble doesn't span the whole file, drop the no newline at diff --git a/clang-tools-extra/clangd/unittests/CompilerTests.cpp b/clang-tools-extra/clangd/unittests/CompilerTests.cpp index ab9e85e983d1c..9c8ad8d70b47b 100644 --- a/clang-tools-extra/clangd/unittests/CompilerTests.cpp +++ b/clang-tools-extra/clangd/unittests/CompilerTests.cpp @@ -7,6 +7,8 @@ //===----------------------------------------------------------------------===// #include "Compiler.h" +#include "Config.h" +#include "Diagnostics.h" #include "TestTU.h" #include "clang/Frontend/DependencyOutputOptions.h" #include "clang/Frontend/FrontendOptions.h" @@ -113,6 +115,19 @@ TEST(BuildCompilerInvocation, EmptyArgs) { // No crash. EXPECT_EQ(buildCompilerInvocation(Inputs, Diags), nullptr); } +TEST(BuildCompilerInvocation, SuppressDiags) { + MockFS FS; + StoreDiags Diags; + TestTU TU; + TU.ExtraArgs = {"-funknown-arg"}; + auto Inputs = TU.inputs(FS); + + Config Cfg; + Cfg.Diagnostics.Suppress = {"drv_unknown_argument"}; + WithContextValue SuppressFilterWithCfg(Config::Key, std::move(Cfg)); + EXPECT_NE(buildCompilerInvocation(Inputs, Diags), nullptr); + EXPECT_THAT(Diags.take(), IsEmpty()); +} } // namespace } // namespace clangd } // namespace clang diff --git a/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp b/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp index 84ceddbd4fc4b..6fe48478e1175 100644 --- a/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp +++ b/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp @@ -2170,6 +2170,27 @@ TEST(DiagnosticsTest, UnusedInHeader) { EXPECT_THAT(TU.build().getDiagnostics(), IsEmpty()); } +TEST(DiagnosticsTest, DontSuppressSubcategories) { + Annotations Source(R"cpp( + /*error-ok*/ + void bar(int x) { + switch(x) { + default: + break; + break; + } + })cpp"); + TestTU TU; + TU.ExtraArgs.push_back("-Wunreachable-code-aggressive"); + TU.Code = Source.code().str(); + Config Cfg; + // This shouldn't suppress subcategory unreachable-break. + Cfg.Diagnostics.Suppress = {"unreachable-code"}; + WithContextValue SuppressFilterWithCfg(Config::Key, std::move(Cfg)); + EXPECT_THAT(TU.build().getDiagnostics(), + ElementsAre(diagName("-Wunreachable-code-break"))); +} + } // namespace } // namespace clangd } // namespace clang _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
