[clang-tools-extra] [clangd][NFC] Add regression coverage for current clang-tidy integration (PR #231461)

Aleksandr Platonov via cfe-commits cfe-commits at lists.llvm.org
Thu Oct 22 04:14:12 PDT 2026


================
@@ -824,6 +828,86 @@ TEST(DiagnosticTest, ClangTidyEnablesClangWarning) {
   EXPECT_THAT(TU.build().getDiagnostics(), SizeIs(1));
 }
 
+TEST(DiagnosticTest, ClangTidyCompilerWarningsWithoutChecks) {
+  auto TU = TestTU::withCode("static void foo() {}");
+  TU.ClangTidyProvider = [](tidy::ClangTidyOptions &Opts, llvm::StringRef) {
+    Opts.Checks = "-*,clang-diagnostic-*";
+    Opts.ExtraArgs = {"-Wunused-function"};
+    Opts.WarningsAsErrors = "clang-diagnostic-unused-function";
+  };
+  auto Warning = AllOf(diagName("-Wunused-function"), diagSource(Diag::Clang),
+                       diagSeverity(DiagnosticsEngine::Warning));
+  EXPECT_THAT(TU.build().getDiagnostics(), ElementsAre(Warning));
+
+  // Without tidy checks, NOLINT and WarningsAsErrors don't affect warnings.
+  TU.Code = "static void foo() {} // NOLINT(clang-diagnostic-unused-function)";
+  EXPECT_THAT(TU.build().getDiagnostics(), ElementsAre(Warning));
+}
+
+TEST(DiagnosticTest, ClangTidyWarningOptionsBeforeBeginSourceFile) {
+  auto Build = [](bool Suppress, bool ExtraArgsBefore) {
+    auto TU = TestTU::withCode("int value;");
+    TU.ClangTidyProvider = [=](tidy::ClangTidyOptions &Opts, llvm::StringRef) {
+      Opts.Checks = "-*";
+      if (Suppress) {
+        auto &Args = ExtraArgsBefore ? Opts.ExtraArgsBefore : Opts.ExtraArgs;
+        Args = {"-Wno-incomplete-umbrella"};
+      }
+    };
+    TU.ExtraArgs = {"-fmodules",
+                    "-fmodule-map-file=" + testPath("module.modulemap")};
+    TU.AdditionalFiles["module.modulemap"] =
+        R"(module M { umbrella "missing" })";
+
+    // Don't build a PCH; count warnings from module-map loading directly.
+    MockFS FS;
+    auto Inputs = TU.inputs(FS);
+    IgnoringDiagConsumer Diags;
+    auto CI = buildCompilerInvocation(Inputs, Diags);
+    ASSERT_TRUE(CI);
+    auto AST = ParsedAST::build(testPath(TU.Filename), Inputs, std::move(CI),
+                                {}, nullptr);
+    ASSERT_TRUE(AST);
+    EXPECT_EQ(AST->getPreprocessor().getDiagnostics().getNumWarnings(),
+              Suppress ? 0u : 1u);
+  };
+  Build(false, false);
+  Build(true, false);
+  Build(true, true);
+}
+
+TEST(DiagnosticTest, ClangTidyRelativeInput) {
+  if (!CLANGD_TIDY_CHECKS)
+    GTEST_SKIP() << "Requires clang-tidy checks";
+  MockFS FS;
+  auto TU = TestTU::withCode("int *p = 0;");
+  TU.Filename = "project/src/test.cpp";
+  TU.AdditionalFiles["project/src/.clang-tidy"] =
+      "Checks: '-*,modernize-use-nullptr'";
+  auto Provider = provideClangTidyFiles(FS);
+  TU.ClangTidyProvider = [&](tidy::ClangTidyOptions &Opts,
+                             llvm::StringRef Filename) {
+    EXPECT_EQ(Filename, testPath(TU.Filename));
+    Provider(Opts, Filename);
+  };
+  auto Inputs = TU.inputs(FS);
+  Inputs.CompileCommand.Directory = testPath("project");
+  // Configuration lookup must use the requested file, not the frontend input.
+  for (auto InputFile : {"src/./test.cpp", "../other/test.cpp"}) {
+    SCOPED_TRACE(InputFile);
+    IgnoringDiagConsumer Diags;
+    auto CI = buildCompilerInvocation(Inputs, Diags);
+    ASSERT_TRUE(CI);
+    auto Kind = CI->getFrontendOpts().Inputs.front().getKind();
+    CI->getFrontendOpts().Inputs = {FrontendInputFile(InputFile, Kind)};
+    auto AST = ParsedAST::build(testPath(TU.Filename), Inputs, std::move(CI),
----------------
ArcsinX wrote:

`Filename` is a file to analyze and `Input` is something from compile command. E.g. we open a file in an editor, it sends request to clangd with URI of file to analyze (became `Filename`). After that clangd tries to find compile command for this file and `Input` related to found compile command.
I guess in compile command filename can be relative and maybe even completely different or missing (unsure that in this case this won't rise any assert).
But seems in real scenarios we adjust compile command to make 'Filename' and `Inputs` to point the same file [here](https://github.com/llvm/llvm-project/blob/main/clang-tools-extra/clangd/CompileCommands.cpp#L319)

https://github.com/llvm/llvm-project/pull/231461


More information about the cfe-commits mailing list