Skip to content

Commit

Permalink
[analyzer] Command line option to show enabled checker list.
Browse files Browse the repository at this point in the history
This patch adds a command line option to list the checkers that were enabled
by analyzer-checker and not disabled by -analyzer-disable-checker.

It can be very useful to debug long command lines when it is not immediately
apparent which checkers are turned on and which checkers are turned off.

Differential Revision: https://reviews.llvm.org/D23060

llvm-svn: 278006
  • Loading branch information
Xazax-hun committed Aug 8, 2016
1 parent 142f4f7 commit c430990
Show file tree
Hide file tree
Showing 9 changed files with 76 additions and 6 deletions.
3 changes: 3 additions & 0 deletions clang/include/clang/Driver/CC1Options.td
Expand Up @@ -114,6 +114,9 @@ def analyzer_disable_all_checks : Flag<["-"], "analyzer-disable-all-checks">,
def analyzer_checker_help : Flag<["-"], "analyzer-checker-help">,
HelpText<"Display the list of analyzer checkers that are available">;

def analyzer_list_enabled_checkers : Flag<["-"], "analyzer-list-enabled-checkers">,
HelpText<"Display the list of enabled analyzer checkers">;

def analyzer_config : Separate<["-"], "analyzer-config">,
HelpText<"Choose analyzer options to enable">;

Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
Expand Up @@ -149,6 +149,7 @@ class AnalyzerOptions : public RefCountedBase<AnalyzerOptions> {
unsigned DisableAllChecks : 1;

unsigned ShowCheckerHelp : 1;
unsigned ShowEnabledCheckerList : 1;
unsigned AnalyzeAll : 1;
unsigned AnalyzerDisplayProgress : 1;
unsigned AnalyzeNestedBlocks : 1;
Expand Down Expand Up @@ -541,6 +542,7 @@ class AnalyzerOptions : public RefCountedBase<AnalyzerOptions> {
AnalysisPurgeOpt(PurgeStmt),
DisableAllChecks(0),
ShowCheckerHelp(0),
ShowEnabledCheckerList(0),
AnalyzeAll(0),
AnalyzerDisplayProgress(0),
AnalyzeNestedBlocks(0),
Expand Down
4 changes: 3 additions & 1 deletion clang/include/clang/StaticAnalyzer/Core/CheckerRegistry.h
Expand Up @@ -127,7 +127,9 @@ class CheckerRegistry {

/// Prints the name and description of all checkers in this registry.
/// This output is not intended to be machine-parseable.
void printHelp(raw_ostream &out, size_t maxNameChars = 30) const ;
void printHelp(raw_ostream &out, size_t maxNameChars = 30) const;
void printList(raw_ostream &out,
SmallVectorImpl<CheckerOptInfo> &opts) const;

private:
mutable CheckerInfoList Checkers;
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/StaticAnalyzer/Frontend/FrontendActions.h
Expand Up @@ -17,6 +17,7 @@
namespace clang {

class Stmt;
class AnalyzerOptions;

namespace ento {

Expand Down Expand Up @@ -52,6 +53,8 @@ class ParseModelFileAction : public ASTFrontendAction {
};

void printCheckerHelp(raw_ostream &OS, ArrayRef<std::string> plugins);
void printEnabledCheckerList(raw_ostream &OS, ArrayRef<std::string> plugins,
const AnalyzerOptions &opts);

} // end GR namespace

Expand Down
1 change: 1 addition & 0 deletions clang/lib/Frontend/CompilerInvocation.cpp
Expand Up @@ -238,6 +238,7 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args,
}

Opts.ShowCheckerHelp = Args.hasArg(OPT_analyzer_checker_help);
Opts.ShowEnabledCheckerList = Args.hasArg(OPT_analyzer_list_enabled_checkers);
Opts.DisableAllChecks = Args.hasArg(OPT_analyzer_disable_all_checks);

Opts.visualizeExplodedGraphWithGraphViz =
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
Expand Up @@ -229,6 +229,11 @@ bool clang::ExecuteCompilerInvocation(CompilerInstance *Clang) {
ento::printCheckerHelp(llvm::outs(), Clang->getFrontendOpts().Plugins);
return true;
}
if (Clang->getAnalyzerOpts()->ShowEnabledCheckerList) {
ento::printEnabledCheckerList(llvm::outs(),
Clang->getFrontendOpts().Plugins,
*Clang->getAnalyzerOpts());
}
#endif

// If there were errors in processing arguments, don't do anything else.
Expand Down
19 changes: 19 additions & 0 deletions clang/lib/StaticAnalyzer/Core/CheckerRegistry.cpp
Expand Up @@ -175,3 +175,22 @@ void CheckerRegistry::printHelp(raw_ostream &out,
out << '\n';
}
}

void CheckerRegistry::printList(
raw_ostream &out, SmallVectorImpl<CheckerOptInfo> &opts) const {
std::sort(Checkers.begin(), Checkers.end(), checkerNameLT);

// Collect checkers enabled by the options.
CheckerInfoSet enabledCheckers;
for (SmallVectorImpl<CheckerOptInfo>::iterator i = opts.begin(),
e = opts.end();
i != e; ++i) {
collectCheckers(Checkers, Packages, *i, enabledCheckers);
}

for (CheckerInfoSet::const_iterator i = enabledCheckers.begin(),
e = enabledCheckers.end();
i != e; ++i) {
out << (*i)->FullName << '\n';
}
}
25 changes: 20 additions & 5 deletions clang/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp
Expand Up @@ -101,18 +101,24 @@ void ClangCheckerRegistry::warnIncompatible(DiagnosticsEngine *diags,
<< pluginAPIVersion;
}

static SmallVector<CheckerOptInfo, 8>
getCheckerOptList(const AnalyzerOptions &opts) {
SmallVector<CheckerOptInfo, 8> checkerOpts;
for (unsigned i = 0, e = opts.CheckersControlList.size(); i != e; ++i) {
const std::pair<std::string, bool> &opt = opts.CheckersControlList[i];
checkerOpts.push_back(CheckerOptInfo(opt.first.c_str(), opt.second));
}
return checkerOpts;
}

std::unique_ptr<CheckerManager>
ento::createCheckerManager(AnalyzerOptions &opts, const LangOptions &langOpts,
ArrayRef<std::string> plugins,
DiagnosticsEngine &diags) {
std::unique_ptr<CheckerManager> checkerMgr(
new CheckerManager(langOpts, &opts));

SmallVector<CheckerOptInfo, 8> checkerOpts;
for (unsigned i = 0, e = opts.CheckersControlList.size(); i != e; ++i) {
const std::pair<std::string, bool> &opt = opts.CheckersControlList[i];
checkerOpts.push_back(CheckerOptInfo(opt.first.c_str(), opt.second));
}
SmallVector<CheckerOptInfo, 8> checkerOpts = getCheckerOptList(opts);

ClangCheckerRegistry allCheckers(plugins, &diags);
allCheckers.initializeManager(*checkerMgr, checkerOpts);
Expand All @@ -137,3 +143,12 @@ void ento::printCheckerHelp(raw_ostream &out, ArrayRef<std::string> plugins) {

ClangCheckerRegistry(plugins).printHelp(out);
}

void ento::printEnabledCheckerList(raw_ostream &out,
ArrayRef<std::string> plugins,
const AnalyzerOptions &opts) {
out << "OVERVIEW: Clang Static Analyzer Enabled Checkers List\n\n";

SmallVector<CheckerOptInfo, 8> checkerOpts = getCheckerOptList(opts);
ClangCheckerRegistry(plugins).printList(out, checkerOpts);
}
20 changes: 20 additions & 0 deletions clang/test/Analysis/analyzer-enabled-checkers.c
@@ -0,0 +1,20 @@
// RUN: %clang -target x86_64-apple-darwin10 --analyze %s -o /dev/null -Xclang -analyzer-checker=core -Xclang -analyzer-list-enabled-checkers > %t 2>&1
// RUN: FileCheck --input-file=%t %s

// CHECK: OVERVIEW: Clang Static Analyzer Enabled Checkers List
// CHECK: core.CallAndMessage
// CHECK: core.DivideZero
// CHECK: core.DynamicTypePropagation
// CHECK: core.NonNullParamChecker
// CHECK: core.NullDereference
// CHECK: core.StackAddressEscape
// CHECK: core.UndefinedBinaryOperatorResult
// CHECK: core.VLASize
// CHECK: core.builtin.BuiltinFunctions
// CHECK: core.builtin.NoReturnFunctions
// CHECK: core.uninitialized.ArraySubscript
// CHECK: core.uninitialized.Assign
// CHECK: core.uninitialized.Branch
// CHECK: core.uninitialized.CapturedBlockVariable
// CHECK: core.uninitialized.UndefReturn

0 comments on commit c430990

Please sign in to comment.