Skip to content

Commit

Permalink
[clang-check] Adjust argument adjusters for clang-check to strip opti…
Browse files Browse the repository at this point in the history
…ons 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
  • Loading branch information
sam-mccall committed Jan 14, 2022
1 parent 263d198 commit bba729a
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 21 deletions.
19 changes: 19 additions & 0 deletions 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}}
}
52 changes: 31 additions & 21 deletions clang/tools/clang-check/ClangCheck.cpp
Expand Up @@ -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();

// 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 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));

// 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;
Expand Down

0 comments on commit bba729a

Please sign in to comment.