]> granicus.if.org Git - clang/commitdiff
Add support for static analysis to clang-check
authorPavel Labath <labath@google.com>
Thu, 6 Jun 2013 12:35:43 +0000 (12:35 +0000)
committerPavel Labath <labath@google.com>
Thu, 6 Jun 2013 12:35:43 +0000 (12:35 +0000)
Summary:
This adds a command line argument '-analyze' to clang-check which runs the
clang static analyzer on the source files.

Reviewers: klimek

CC: cfe-commits, revane
Differential Revision: http://llvm-reviews.chandlerc.com/D926

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

test/Tooling/clang-check-analyzer.cpp [new file with mode: 0644]
tools/clang-check/CMakeLists.txt
tools/clang-check/ClangCheck.cpp

diff --git a/test/Tooling/clang-check-analyzer.cpp b/test/Tooling/clang-check-analyzer.cpp
new file mode 100644 (file)
index 0000000..16cf7ce
--- /dev/null
@@ -0,0 +1,4 @@
+// RUN: clang-check -analyze "%s" -- -c 2>&1 | FileCheck %s
+
+// CHECK: Dereference of null pointer
+int a(int *x) { if(x){} *x = 47; }
index e8d0d0a18abd4f17ca00e3e1433944d336e9913a..2070de37fcf528dac255b51767919e05fb2ed713 100644 (file)
@@ -14,6 +14,7 @@ target_link_libraries(clang-check
   clangTooling
   clangBasic
   clangRewriteFrontend
+  clangStaticAnalyzerFrontend
   )
 
 install(TARGETS clang-check
index 05783620ca3eb74e6994f756a53d394a74aadf50..bc01874bcf6efbbd649328923be6b622fe63e64c 100644 (file)
@@ -21,6 +21,7 @@
 #include "clang/Driver/Options.h"
 #include "clang/Frontend/ASTConsumers.h"
 #include "clang/Frontend/CompilerInstance.h"
+#include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
 #include "clang/Rewrite/Frontend/FixItRewriter.h"
 #include "clang/Rewrite/Frontend/FrontendActions.h"
 #include "clang/Tooling/CommonOptionsParser.h"
@@ -62,6 +63,9 @@ static cl::opt<bool> ASTPrint(
 static cl::opt<std::string> ASTDumpFilter(
     "ast-dump-filter",
     cl::desc(Options->getOptionHelpText(options::OPT_ast_dump_filter)));
+static cl::opt<bool> Analyze(
+    "analyze",
+    cl::desc(Options->getOptionHelpText(options::OPT_analyze)));
 
 static cl::opt<bool> Fixit(
     "fixit",
@@ -136,6 +140,10 @@ public:
     : Extra(Extra), Pos(Pos) {
   }
 
+  InsertAdjuster(const char *Extra, Position Pos)
+    : Extra(1, std::string(Extra)), Pos(Pos) {
+  }
+
   virtual CommandLineArguments
   Adjust(const CommandLineArguments &Args) LLVM_OVERRIDE {
     CommandLineArguments Return(Args);
@@ -182,13 +190,33 @@ int main(int argc, const char **argv) {
   ClangTool Tool(OptionsParser.getCompilations(),
                  OptionsParser.getSourcePathList());
 
-  if (ArgsAfter.size() > 0)
-    Tool.appendArgumentsAdjuster(new InsertAdjuster(ArgsAfter, InsertAdjuster::END));
-  if (ArgsBefore.size() > 0)
-    Tool.appendArgumentsAdjuster(new InsertAdjuster(ArgsBefore, InsertAdjuster::BEGIN));
+  // Clear adjusters because -fsyntax-only is inserted by the default chain.
+  Tool.clearArgumentsAdjusters();
+  Tool.appendArgumentsAdjuster(new ClangStripOutputAdjuster());
+  if (ArgsAfter.size() > 0) {
+    Tool.appendArgumentsAdjuster(new InsertAdjuster(ArgsAfter,
+          InsertAdjuster::END));
+  }
+  if (ArgsBefore.size() > 0) {
+    Tool.appendArgumentsAdjuster(new InsertAdjuster(ArgsBefore,
+          InsertAdjuster::BEGIN));
+  }
+
+  // Running the analyzer requires --analyze. Other modes can work with the
+  // -fsyntax-only option.
+  Tool.appendArgumentsAdjuster(new InsertAdjuster(
+        Analyze ? "--analyze" : "-fsyntax-only", InsertAdjuster::BEGIN));
+
+  clang_check::ClangCheckActionFactory CheckFactory;
+  FrontendActionFactory *FrontendFactory;
+
+  // Choose the correct factory based on the selected mode.
+  if (Analyze)
+    FrontendFactory = newFrontendActionFactory<clang::ento::AnalysisAction>();
+  else if (Fixit)
+    FrontendFactory = newFrontendActionFactory<FixItAction>();
+  else
+    FrontendFactory = newFrontendActionFactory(&CheckFactory);
 
-  if (Fixit)
-    return Tool.run(newFrontendActionFactory<FixItAction>());
-  clang_check::ClangCheckActionFactory Factory;
-  return Tool.run(newFrontendActionFactory(&Factory));
+  return Tool.run(FrontendFactory);
 }