================
@@ -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
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits