[clang-check] Adjust argument adjusters for clang-check to strip options blocking the static analyzer

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.

Reviewed By: sammccall

Differential Revision: https://reviews.llvm.org/D116329
This commit is contained in:
Sam McCall 2022-01-14 08:34:11 +01:00
parent 263d1986e3
commit bba729af3e
2 changed files with 49 additions and 20 deletions

View file

@ -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}}
}

View file

@ -208,27 +208,37 @@ int main(int argc, const char **argv) {
ClangTool Tool(OptionsParser.getCompilations(),
OptionsParser.getSourcePathList());
// Clear adjusters because -fsyntax-only is inserted by the default chain.
Tool.clearArgumentsAdjusters();
if (Analyze) {
// Set output path if is provided by user.
//
// As the original -o options have been removed by default via the
// strip-output adjuster, we only need to add the analyzer -o options here
// when it is provided by users.
if (!AnalyzerOutput.empty())
Tool.appendArgumentsAdjuster(
getInsertArgumentAdjuster(CommandLineArguments{"-o", AnalyzerOutput},
ArgumentInsertPosition::END));
// 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));
// Running the analyzer requires --analyze. Other modes can work with the
// -fsyntax-only option.
//
// The syntax-only adjuster is installed by default.
// Good: It also strips options that trigger extra output, like -save-temps.
// Bad: We don't want the -fsyntax-only when executing the static analyzer.
//
// To enable the static analyzer, we first strip all -fsyntax-only options
// and then add an --analyze option to the front.
Tool.appendArgumentsAdjuster(
[&](const CommandLineArguments &Args, StringRef /*unused*/) {
CommandLineArguments AdjustedArgs;
for (const std::string &Arg : Args)
if (Arg != "-fsyntax-only")
AdjustedArgs.emplace_back(Arg);
return AdjustedArgs;
});
Tool.appendArgumentsAdjuster(
getInsertArgumentAdjuster("--analyze", ArgumentInsertPosition::BEGIN));
}
ClangCheckActionFactory CheckFactory;
std::unique_ptr<FrontendActionFactory> FrontendFactory;