OikawaKirie created this revision. OikawaKirie added reviewers: kbobyrev, sammccall, labath. OikawaKirie added a project: clang. Herald added subscribers: manas, ASDenysPetrov, dkrupp, donat.nagy, Szelethus, a.sidorin, baloghadamsoftware. OikawaKirie requested review of this revision. Herald added a subscriber: cfe-commits.
Output generation options (like `-save-temps`) will make the analyzer not executed even `--analyze` option is provided in the driver arguments. Besides, the original approach of adding `--analyze` option will not work when (more than one) `-fsyntax-only` options are provided in the driver arguments. This patch fixes these two problems by using the syntax-only adjuster to remove output generation options and manually filter out redundant `-fsyntax-only` options. In the new implementation, the adjusters added by `ClangTool` will not be removed but used as dependencies for clang-check adjusters for analyzer options. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D116329 Files: clang/test/Tooling/clang-check-analyze-save-temps.cpp clang/tools/clang-check/ClangCheck.cpp Index: clang/tools/clang-check/ClangCheck.cpp =================================================================== --- clang/tools/clang-check/ClangCheck.cpp +++ clang/tools/clang-check/ClangCheck.cpp @@ -208,27 +208,39 @@ ClangTool Tool(OptionsParser.getCompilations(), OptionsParser.getSourcePathList()); - // Clear adjusters because -fsyntax-only is inserted by the default chain. - Tool.clearArgumentsAdjusters(); - - // Reset output path if is provided by user. - Tool.appendArgumentsAdjuster( - Analyze ? [&](const CommandLineArguments &Args, StringRef File) { - auto Ret = getClangStripOutputAdjuster()(Args, File); - if (!AnalyzerOutput.empty()) { - Ret.emplace_back("-o"); - Ret.emplace_back(AnalyzerOutput); - } - return Ret; - } - : getClangStripOutputAdjuster()); - - Tool.appendArgumentsAdjuster(getClangStripDependencyFileAdjuster()); - - // Running the analyzer requires --analyze. Other modes can work with the - // -fsyntax-only option. - Tool.appendArgumentsAdjuster(getInsertArgumentAdjuster( - Analyze ? "--analyze" : "-fsyntax-only", ArgumentInsertPosition::BEGIN)); + if (Analyze) { + // Set output path if is provided by user. + // + // As the original -o options have been removed by strip-output adjuster, we + // only need to add the analyzer -o options here. + if (!AnalyzerOutput.empty()) { + Tool.appendArgumentsAdjuster(getInsertArgumentAdjuster("-o")); + Tool.appendArgumentsAdjuster( + getInsertArgumentAdjuster(AnalyzerOutput.c_str())); + } + + // Running the analyzer requires --analyze. Other modes can work with the + // -fsyntax-only option. + // + // The syntax-only adjuster can also help us to remove other options that + // trigger output generation, e.g. -save-temps. Besides, to enable the + // analyzer, we also need to replace the first -fsyntax-only option with + // option --analyze, and remove redundant ones. + Tool.appendArgumentsAdjuster( + [&](const CommandLineArguments &Args, StringRef /*unused*/) { + CommandLineArguments AdjustedArgs; + bool HasAnalyze = false; + for (const StringRef Arg : Args) { + if (Arg != "-fsyntax-only") { + AdjustedArgs.emplace_back(Arg); + } else if (!HasAnalyze) { + AdjustedArgs.emplace_back("--analyze"); + HasAnalyze = true; + } + } + return AdjustedArgs; + }); + } ClangCheckActionFactory CheckFactory; std::unique_ptr<FrontendActionFactory> FrontendFactory; Index: clang/test/Tooling/clang-check-analyze-save-temps.cpp =================================================================== --- /dev/null +++ clang/test/Tooling/clang-check-analyze-save-temps.cpp @@ -0,0 +1,19 @@ +// Check whether output generation options (like -save-temps) will not affect +// the execution of the analyzer. + +// RUN: clang-check -analyze %s -- -save-temps -c -Xclang -verify + + +// Check whether redundant -fsyntax-only options will affect the execution of +// the analyzer. + +// RUN: clang-check -analyze %s -- \ +// RUN: -fsyntax-only -c -fsyntax-only -Xclang -verify 2>&1 | \ +// RUN: FileCheck %s --allow-empty + +// CHECK-NOT: argument unused during compilation: '--analyze' + +void a(int *x) { + if (x) { } + *x = 47; // expected-warning {{Dereference of null pointer}} +}
Index: clang/tools/clang-check/ClangCheck.cpp =================================================================== --- clang/tools/clang-check/ClangCheck.cpp +++ clang/tools/clang-check/ClangCheck.cpp @@ -208,27 +208,39 @@ ClangTool Tool(OptionsParser.getCompilations(), OptionsParser.getSourcePathList()); - // Clear adjusters because -fsyntax-only is inserted by the default chain. - Tool.clearArgumentsAdjusters(); - - // Reset output path if is provided by user. - Tool.appendArgumentsAdjuster( - Analyze ? [&](const CommandLineArguments &Args, StringRef File) { - auto Ret = getClangStripOutputAdjuster()(Args, File); - if (!AnalyzerOutput.empty()) { - Ret.emplace_back("-o"); - Ret.emplace_back(AnalyzerOutput); - } - return Ret; - } - : getClangStripOutputAdjuster()); - - Tool.appendArgumentsAdjuster(getClangStripDependencyFileAdjuster()); - - // Running the analyzer requires --analyze. Other modes can work with the - // -fsyntax-only option. - Tool.appendArgumentsAdjuster(getInsertArgumentAdjuster( - Analyze ? "--analyze" : "-fsyntax-only", ArgumentInsertPosition::BEGIN)); + if (Analyze) { + // Set output path if is provided by user. + // + // As the original -o options have been removed by strip-output adjuster, we + // only need to add the analyzer -o options here. + if (!AnalyzerOutput.empty()) { + Tool.appendArgumentsAdjuster(getInsertArgumentAdjuster("-o")); + Tool.appendArgumentsAdjuster( + getInsertArgumentAdjuster(AnalyzerOutput.c_str())); + } + + // Running the analyzer requires --analyze. Other modes can work with the + // -fsyntax-only option. + // + // The syntax-only adjuster can also help us to remove other options that + // trigger output generation, e.g. -save-temps. Besides, to enable the + // analyzer, we also need to replace the first -fsyntax-only option with + // option --analyze, and remove redundant ones. + Tool.appendArgumentsAdjuster( + [&](const CommandLineArguments &Args, StringRef /*unused*/) { + CommandLineArguments AdjustedArgs; + bool HasAnalyze = false; + for (const StringRef Arg : Args) { + if (Arg != "-fsyntax-only") { + AdjustedArgs.emplace_back(Arg); + } else if (!HasAnalyze) { + AdjustedArgs.emplace_back("--analyze"); + HasAnalyze = true; + } + } + return AdjustedArgs; + }); + } ClangCheckActionFactory CheckFactory; std::unique_ptr<FrontendActionFactory> FrontendFactory; Index: clang/test/Tooling/clang-check-analyze-save-temps.cpp =================================================================== --- /dev/null +++ clang/test/Tooling/clang-check-analyze-save-temps.cpp @@ -0,0 +1,19 @@ +// Check whether output generation options (like -save-temps) will not affect +// the execution of the analyzer. + +// RUN: clang-check -analyze %s -- -save-temps -c -Xclang -verify + + +// Check whether redundant -fsyntax-only options will affect the execution of +// the analyzer. + +// RUN: clang-check -analyze %s -- \ +// RUN: -fsyntax-only -c -fsyntax-only -Xclang -verify 2>&1 | \ +// RUN: FileCheck %s --allow-empty + +// CHECK-NOT: argument unused during compilation: '--analyze' + +void a(int *x) { + if (x) { } + *x = 47; // expected-warning {{Dereference of null pointer}} +}
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits