]> granicus.if.org Git - clang/commitdiff
[analyzer] Command line option to show enabled checker list.
authorGabor Horvath <xazax.hun@gmail.com>
Mon, 8 Aug 2016 13:41:04 +0000 (13:41 +0000)
committerGabor Horvath <xazax.hun@gmail.com>
Mon, 8 Aug 2016 13:41:04 +0000 (13:41 +0000)
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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@278006 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Driver/CC1Options.td
include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
include/clang/StaticAnalyzer/Core/CheckerRegistry.h
include/clang/StaticAnalyzer/Frontend/FrontendActions.h
lib/Frontend/CompilerInvocation.cpp
lib/FrontendTool/ExecuteCompilerInvocation.cpp
lib/StaticAnalyzer/Core/CheckerRegistry.cpp
lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp
test/Analysis/analyzer-enabled-checkers.c [new file with mode: 0644]

index aa8352204b6f527111ee3caed3a701292f7a75be..f2cfc11c9cec73a4927ed31b4c3f620bb3800724 100644 (file)
@@ -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">;
 
index 3959de24d431d8413e4f26fc32400d4cd3d0386b..fe8aea5d821352e4450c71f2e2c5d47dd17ccaa9 100644 (file)
@@ -149,6 +149,7 @@ public:
   unsigned DisableAllChecks : 1;
 
   unsigned ShowCheckerHelp : 1;
+  unsigned ShowEnabledCheckerList : 1;
   unsigned AnalyzeAll : 1;
   unsigned AnalyzerDisplayProgress : 1;
   unsigned AnalyzeNestedBlocks : 1;
@@ -541,6 +542,7 @@ public:
     AnalysisPurgeOpt(PurgeStmt),
     DisableAllChecks(0),
     ShowCheckerHelp(0),
+    ShowEnabledCheckerList(0),
     AnalyzeAll(0),
     AnalyzerDisplayProgress(0),
     AnalyzeNestedBlocks(0),
index c9724c08da2d110bca3eafbc69df82d269aac35c..3b26ed3e1a09a01f0994a3e906df31319e330a02 100644 (file)
@@ -127,7 +127,9 @@ public:
 
   /// 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;
index 36afb4bc5d73e732a993e75632ba9100189c750f..e66d48b1be1ddc239aafccfcf9082303180459b6 100644 (file)
@@ -17,6 +17,7 @@
 namespace clang {
 
 class Stmt;
+class AnalyzerOptions;
 
 namespace ento {
 
@@ -52,6 +53,8 @@ private:
 };
 
 void printCheckerHelp(raw_ostream &OS, ArrayRef<std::string> plugins);
+void printEnabledCheckerList(raw_ostream &OS, ArrayRef<std::string> plugins,
+                             const AnalyzerOptions &opts);
 
 } // end GR namespace
 
index cfbc40be94caf016a3c08c906e286e7891937cf7..9a18a6365faa970dc92e16b9f5dba8007697f3c2 100644 (file)
@@ -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 =
index 509c326d1597a498a43e4a4c32e3f90e2e78f099..13cb52aa1e3fce8b8e15fd3518b7485683fdbcf2 100644 (file)
@@ -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.
index ba03e2f8a3c18d8dc84fbf878ff789612f327c89..c9cb189a5b7294ad03d851d53532ecf407f799e5 100644 (file)
@@ -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';
+  }
+}
index 75fa4c651ace7036c8a0410bb766f2cd868d6536..1668aebf3f968f7b4016d0d9bb3e02b4a11d3ed4 100644 (file)
@@ -101,6 +101,16 @@ 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,
@@ -108,11 +118,7 @@ ento::createCheckerManager(AnalyzerOptions &opts, const LangOptions &langOpts,
   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);
@@ -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);
+}
diff --git a/test/Analysis/analyzer-enabled-checkers.c b/test/Analysis/analyzer-enabled-checkers.c
new file mode 100644 (file)
index 0000000..e60de05
--- /dev/null
@@ -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
+