]> granicus.if.org Git - clang/commitdiff
[analyzer] Migrate UndefBranchChecker to CheckerV2.
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Mon, 28 Feb 2011 01:27:33 +0000 (01:27 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Mon, 28 Feb 2011 01:27:33 +0000 (01:27 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126616 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/StaticAnalyzer/Core/CheckerManager.h
include/clang/StaticAnalyzer/Core/CheckerV2.h
lib/StaticAnalyzer/Checkers/Checkers.td
lib/StaticAnalyzer/Checkers/ExprEngine.cpp
lib/StaticAnalyzer/Checkers/InternalChecks.h
lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
lib/StaticAnalyzer/Core/CheckerManager.cpp
test/Analysis/new.cpp

index f7ee2bed8d08922a3022aca4f5c7fc49ef42d3d0..3c23cbd29f38aa1d241329bbb99b59b7cca5b2fa 100644 (file)
@@ -37,6 +37,7 @@ namespace ento {
   class ExplodedGraph;
   class GRState;
   class EndOfFunctionNodeBuilder;
+  class BranchNodeBuilder;
   class MemRegion;
   class SymbolReaper;
 
@@ -202,6 +203,10 @@ public:
   /// \brief Run checkers for end of path.
   void runCheckersForEndPath(EndOfFunctionNodeBuilder &B, ExprEngine &Eng);
 
+  /// \brief Run checkers for branch condition.
+  void runCheckersForBranchCondition(const Stmt *condition,
+                                     BranchNodeBuilder &B, ExprEngine &Eng);
+
   /// \brief Run checkers for live symbols.
   void runCheckersForLiveSymbols(const GRState *state,
                                  SymbolReaper &SymReaper);
@@ -239,7 +244,6 @@ public:
 
   typedef CheckerFn<const Decl *, AnalysisManager&, BugReporter &>
       CheckDeclFunc;
-  typedef CheckerFn<const Stmt *, CheckerContext &> CheckStmtFunc;
 
   typedef bool (*HandlesDeclFunc)(const Decl *D);
   void _registerForDecl(CheckDeclFunc checkfn, HandlesDeclFunc isForDeclFn);
@@ -250,6 +254,7 @@ public:
 // Internal registration functions for path-sensitive checking.
 //===----------------------------------------------------------------------===//
 
+  typedef CheckerFn<const Stmt *, CheckerContext &> CheckStmtFunc;
   typedef CheckerFn<const ObjCMessage &, CheckerContext &> CheckObjCMessageFunc;
   typedef CheckerFn<const SVal &/*location*/, bool/*isLoad*/, CheckerContext &>
       CheckLocationFunc;
@@ -258,6 +263,8 @@ public:
   typedef CheckerFn<ExplodedGraph &, BugReporter &, ExprEngine &>
       CheckEndAnalysisFunc;
   typedef CheckerFn<EndOfFunctionNodeBuilder &, ExprEngine &> CheckEndPathFunc;
+  typedef CheckerFn<const Stmt *, BranchNodeBuilder &, ExprEngine &>
+      CheckBranchConditionFunc;
   typedef CheckerFn<SymbolReaper &, CheckerContext &> CheckDeadSymbolsFunc;
   typedef CheckerFn<const GRState *, SymbolReaper &> CheckLiveSymbolsFunc;
 
@@ -278,6 +285,8 @@ public:
 
   void _registerForEndPath(CheckEndPathFunc checkfn);
 
+  void _registerForBranchCondition(CheckBranchConditionFunc checkfn);
+
   void _registerForLiveSymbols(CheckLiveSymbolsFunc checkfn);
 
   void _registerForDeadSymbols(CheckDeadSymbolsFunc checkfn);
@@ -415,6 +424,8 @@ private:
 
   std::vector<CheckEndPathFunc> EndPathCheckers;
 
+  std::vector<CheckBranchConditionFunc> BranchConditionCheckers;
+
   std::vector<CheckLiveSymbolsFunc> LiveSymbolsCheckers;
 
   std::vector<CheckDeadSymbolsFunc> DeadSymbolsCheckers;
index 7dbbd32ae974ceeaa9aa14ec793b968675149ee8..931cee9931bacf5d4706578316c33d03b92d9360 100644 (file)
@@ -190,6 +190,22 @@ public:
   }
 };
 
+class BranchCondition {
+  template <typename CHECKER>
+  static void _checkBranchCondition(void *checker, const Stmt *condition,
+                                    BranchNodeBuilder &B, ExprEngine &Eng) {
+    ((const CHECKER *)checker)->checkBranchCondition(condition, B, Eng);
+  }
+
+public:
+  template <typename CHECKER>
+  static void _register(CHECKER *checker, CheckerManager &mgr) {
+    mgr._registerForBranchCondition(
+      CheckerManager::CheckBranchConditionFunc(checker,
+                                               _checkBranchCondition<CHECKER>));
+  }
+};
+
 class LiveSymbols {
   template <typename CHECKER>
   static void _checkLiveSymbols(void *checker, const GRState *state,
index 6599b96b003038ce192d760bd49c1203dd272489..1a2205fd5b69fd08cb46da599c1d0f83971ed8ac 100644 (file)
@@ -75,6 +75,10 @@ def ObjCUnusedIvarsChecker : Checker<"UnusedIvars">,
 
 let ParentPackage = Core in {
 
+def UndefBranchChecker : Checker<"UndefBranch">,
+  HelpText<"Check for undefined branch conditions">,
+  DescFile<"UndefBranchChecker.cpp">;
+
 def UndefCapturedBlockVarChecker : Checker<"UndefBlockVar">,
   HelpText<"Check for blocks that capture uninitialized values">,
   DescFile<"UndefCapturedBlockVarChecker.cpp">;
index f39c7b9d73fe6a84417bb4ae7e1c244285b8d7a1..00d13783cb6bbd0abe198fadd83812f96cbf1531 100644 (file)
@@ -330,7 +330,6 @@ static void RegisterInternalChecks(ExprEngine &Eng) {
   RegisterReturnUndefChecker(Eng);
   RegisterUndefinedArraySubscriptChecker(Eng);
   RegisterUndefinedAssignmentChecker(Eng);
-  RegisterUndefBranchChecker(Eng);
 }
 
 ExprEngine::ExprEngine(AnalysisManager &mgr, TransferFuncs *tf)
@@ -1319,6 +1318,8 @@ void ExprEngine::processBranch(const Stmt* Condition, const Stmt* Term,
     checker->VisitBranchCondition(builder, *this, Condition, tag);
   }
 
+  getCheckerManager().runCheckersForBranchCondition(Condition, builder, *this);
+
   // If the branch condition is undefined, return;
   if (!builder.isFeasible(true) && !builder.isFeasible(false))
     return;
index 421b616456dd4353239975f30603c3a5db3edfbb..42bd9687dcf53cfd502d409ef4068e42cd042b29 100644 (file)
@@ -28,7 +28,6 @@ void RegisterCallAndMessageChecker(ExprEngine &Eng);
 void RegisterDereferenceChecker(ExprEngine &Eng);
 void RegisterDivZeroChecker(ExprEngine &Eng);
 void RegisterReturnUndefChecker(ExprEngine &Eng);
-void RegisterUndefBranchChecker(ExprEngine &Eng);
 void RegisterUndefinedArraySubscriptChecker(ExprEngine &Eng);
 void RegisterUndefinedAssignmentChecker(ExprEngine &Eng);
 void RegisterVLASizeChecker(ExprEngine &Eng);
index 14ae9edc7b7e903acf2c5ea22cbf30e4a6a47255..0902d91fffa4f65590d2e88626e44a236136613d 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
-#include "InternalChecks.h"
+#include "ClangSACheckers.h"
+#include "clang/StaticAnalyzer/Core/CheckerV2.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/Checker.h"
 
 using namespace clang;
 using namespace ento;
 
 namespace {
 
-class UndefBranchChecker : public Checker {
-  BuiltinBug *BT;
+class UndefBranchChecker : public CheckerV2<check::BranchCondition> {
+  mutable llvm::OwningPtr<BuiltinBug> BT;
 
   struct FindUndefExpr {
     GRStateManager& VM;
@@ -48,26 +50,15 @@ class UndefBranchChecker : public Checker {
   };
 
 public:
-  UndefBranchChecker() : BT(0) {}
-  static void *getTag();
-  void VisitBranchCondition(BranchNodeBuilder &Builder, ExprEngine &Eng,
-                            const Stmt *Condition, void *tag);
+  void checkBranchCondition(const Stmt *Condition, BranchNodeBuilder &Builder,
+                            ExprEngine &Eng) const;
 };
 
 }
 
-void ento::RegisterUndefBranchChecker(ExprEngine &Eng) {
-  Eng.registerCheck(new UndefBranchChecker());
-}
-
-void *UndefBranchChecker::getTag() {
-  static int x;
-  return &x;
-}
-
-void UndefBranchChecker::VisitBranchCondition(BranchNodeBuilder &Builder, 
-                                              ExprEngine &Eng,
-                                              const Stmt *Condition, void *tag){
+void UndefBranchChecker::checkBranchCondition(const Stmt *Condition,
+                                              BranchNodeBuilder &Builder,
+                                              ExprEngine &Eng) const {
   const GRState *state = Builder.getState();
   SVal X = state->getSVal(Condition);
   if (X.isUndef()) {
@@ -75,7 +66,8 @@ void UndefBranchChecker::VisitBranchCondition(BranchNodeBuilder &Builder,
     if (N) {
       N->markAsSink();
       if (!BT)
-        BT = new BuiltinBug("Branch condition evaluates to a garbage value");
+        BT.reset(
+               new BuiltinBug("Branch condition evaluates to a garbage value"));
 
       // What's going on here: we want to highlight the subexpression of the
       // condition that is the most likely source of the "uninitialized
@@ -118,3 +110,7 @@ void UndefBranchChecker::VisitBranchCondition(BranchNodeBuilder &Builder,
     Builder.markInfeasible(false);
   }
 }
+
+void ento::registerUndefBranchChecker(CheckerManager &mgr) {
+  mgr.registerChecker<UndefBranchChecker>();
+}
index 0a4e847ef4d65c19360710b2ffce0c5350c99371..4776f5702dd137bcc155b888fa6d1f4912d10695 100644 (file)
@@ -256,6 +256,16 @@ void CheckerManager::runCheckersForEndPath(EndOfFunctionNodeBuilder &B,
   }
 }
 
+/// \brief Run checkers for branch condition.
+void CheckerManager::runCheckersForBranchCondition(const Stmt *condition,
+                                                   BranchNodeBuilder &B,
+                                                   ExprEngine &Eng) {
+  for (unsigned i = 0, e = BranchConditionCheckers.size(); i != e; ++i) {
+    CheckBranchConditionFunc fn = BranchConditionCheckers[i];
+    fn(condition, B, Eng);
+  }
+}
+
 /// \brief Run checkers for live symbols.
 void CheckerManager::runCheckersForLiveSymbols(const GRState *state,
                                                SymbolReaper &SymReaper) {
@@ -431,6 +441,11 @@ void CheckerManager::_registerForEndPath(CheckEndPathFunc checkfn) {
   EndPathCheckers.push_back(checkfn);
 }
 
+void CheckerManager::_registerForBranchCondition(
+                                             CheckBranchConditionFunc checkfn) {
+  BranchConditionCheckers.push_back(checkfn);
+}
+
 void CheckerManager::_registerForLiveSymbols(CheckLiveSymbolsFunc checkfn) {
   LiveSymbolsCheckers.push_back(checkfn);
 }
index f26eecd4b196a9a39946109f946118547371a961..b32063788f2386b50150cd470ac57168b627a2a7 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store region -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-checker=core -analyzer-store region -verify %s
 
 void f1() {
   int *n = new int;