]> granicus.if.org Git - clang/commitdiff
[analyzer] Make branch for condition callback use CheckerContext
authorAnna Zaks <ganna@apple.com>
Tue, 25 Oct 2011 19:56:54 +0000 (19:56 +0000)
committerAnna Zaks <ganna@apple.com>
Tue, 25 Oct 2011 19:56:54 +0000 (19:56 +0000)
Now, all the path sensitive checkers use CheckerContext!

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

include/clang/StaticAnalyzer/Core/Checker.h
include/clang/StaticAnalyzer/Core/CheckerManager.h
lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
lib/StaticAnalyzer/Core/CheckerManager.cpp
lib/StaticAnalyzer/Core/ExprEngine.cpp

index 181080a21345b4876dd555d9a1eed925aa829254..358510ef0b08eee6d27fb2b8ac19981ee3e0d9d9 100644 (file)
@@ -214,10 +214,9 @@ public:
 
 class BranchCondition {
   template <typename CHECKER>
-  static void _checkBranchCondition(void *checker, const Stmt *condition,
-                                    NodeBuilder &B, ExplodedNode *Pred,
-                                    ExprEngine &Eng) {
-    ((const CHECKER *)checker)->checkBranchCondition(condition, B, Pred, Eng);
+  static void _checkBranchCondition(void *checker, const Stmt *Condition,
+                                    CheckerContext & C) {
+    ((const CHECKER *)checker)->checkBranchCondition(Condition, C);
   }
 
 public:
index e74bd8b826ad8b26d79681c4fa424643f6e6a79c..806085460baef86f527046538c4213b2d7527fdb 100644 (file)
@@ -236,7 +236,7 @@ public:
 
   /// \brief Run checkers for branch condition.
   void runCheckersForBranchCondition(const Stmt *condition,
-                                     NodeBuilder &B, ExplodedNode *Pred,
+                                     ExplodedNodeSet &Dst, ExplodedNode *Pred,
                                      ExprEngine &Eng);
 
   /// \brief Run checkers for live symbols.
@@ -339,8 +339,7 @@ public:
   typedef CheckerFn<void (CheckerContext &)>
       CheckEndPathFunc;
   
-  typedef CheckerFn<void (const Stmt *, NodeBuilder &, ExplodedNode *Pred,
-                          ExprEngine &)>
+  typedef CheckerFn<void (const Stmt *, CheckerContext &)>
       CheckBranchConditionFunc;
   
   typedef CheckerFn<void (SymbolReaper &, CheckerContext &)>
index d030469459fecebfbe3d4663aa74c79a0f01d961..afb79b5d166f3663cf6ad51e7c73743d8503093d 100644 (file)
@@ -49,27 +49,18 @@ class UndefBranchChecker : public Checker<check::BranchCondition> {
   };
 
 public:
-  void checkBranchCondition(const Stmt *Condition, NodeBuilder &Builder,
-                            ExplodedNode *Pred, ExprEngine &Eng) const;
+  void checkBranchCondition(const Stmt *Condition, CheckerContext &Ctx) const;
 };
 
 }
 
 void UndefBranchChecker::checkBranchCondition(const Stmt *Condition,
-                                              NodeBuilder &Builder,
-                                              ExplodedNode *Pred,
-                                              ExprEngine &Eng) const {
-  const ProgramState *state = Pred->getState();
-  SVal X = state->getSVal(Condition);
+                                              CheckerContext &Ctx) const {
+  SVal X = Ctx.getState()->getSVal(Condition);
   if (X.isUndef()) {
-    // TODO: The PP will be generated with the correct tag by the CheckerManager
-    // after we migrate the callback to CheckerContext.
-    const ProgramPointTag *Tag = 0;
-    ProgramPoint PP = PostCondition(Condition, Pred->getLocationContext(), Tag);
     // Generate a sink node, which implicitly marks both outgoing branches as
     // infeasible.
-    ExplodedNode *N = Builder.generateNode(PP, state,
-                                           Pred, true);
+    ExplodedNode *N = Ctx.generateSink();
     if (N) {
       if (!BT)
         BT.reset(
@@ -107,7 +98,7 @@ void UndefBranchChecker::checkBranchCondition(const Stmt *Condition,
       R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, Ex));
       R->addRange(Ex->getSourceRange());
 
-      Eng.getBugReporter().EmitReport(R);
+      Ctx.EmitReport(R);
     }
   }
 }
index 67fe4d6ca219ccb592bb09679228e9e0fdd628d0..ecb1a7a4ce3aa8eb50d42888dbb9093c0e14b72f 100644 (file)
@@ -320,15 +320,39 @@ void CheckerManager::runCheckersForEndPath(NodeBuilderContext &BC,
   }
 }
 
+namespace {
+  struct CheckBranchConditionContext {
+    typedef std::vector<CheckerManager::CheckBranchConditionFunc> CheckersTy;
+    const CheckersTy &Checkers;
+    const Stmt *Condition;
+    ExprEngine &Eng;
+
+    CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); }
+    CheckersTy::const_iterator checkers_end() { return Checkers.end(); }
+
+    CheckBranchConditionContext(const CheckersTy &checkers,
+                                const Stmt *Cond, ExprEngine &eng)
+      : Checkers(checkers), Condition(Cond), Eng(eng) {}
+
+    void runChecker(CheckerManager::CheckBranchConditionFunc checkFn,
+                    NodeBuilder &Bldr, ExplodedNode *Pred) {
+      ProgramPoint L = PostCondition(Condition, Pred->getLocationContext(),
+                                     checkFn.Checker);
+      CheckerContext C(Bldr, Eng, Pred, L, 0);
+      checkFn(Condition, C);
+    }
+  };
+}
+
 /// \brief Run checkers for branch condition.
-void CheckerManager::runCheckersForBranchCondition(const Stmt *condition,
-                                                   NodeBuilder &B,
+void CheckerManager::runCheckersForBranchCondition(const Stmt *Condition,
+                                                   ExplodedNodeSet &Dst,
                                                    ExplodedNode *Pred,
                                                    ExprEngine &Eng) {
-  for (unsigned i = 0, e = BranchConditionCheckers.size(); i != e; ++i) {
-    CheckBranchConditionFunc fn = BranchConditionCheckers[i];
-    fn(condition, B, Pred, Eng);
-  }
+  ExplodedNodeSet Src;
+  Src.insert(Pred);
+  CheckBranchConditionContext C(BranchConditionCheckers, Condition, Eng);
+  expandGraphWithCheckers(C, Dst, Src);
 }
 
 /// \brief Run checkers for live symbols.
index 3e5a31cda001565dc83b9db53e6eec413250e0e3..8ba2cd80a22e5e7b5353a719effba29db0ece5d3 100644 (file)
@@ -217,10 +217,13 @@ void ExprEngine::processCFGElement(const CFGElement E, ExplodedNode *Pred,
       ProcessImplicitDtor(*E.getAs<CFGImplicitDtor>(), Pred);
       return;
   }
+  currentStmtIdx = 0;
+  currentBuilderContext = 0;
 }
 
 const Stmt *ExprEngine::getStmt() const {
-  const CFGStmt *CS = (*currentBuilderContext->getBlock())[currentStmtIdx].getAs<CFGStmt>();
+  const CFGStmt *CS = (*currentBuilderContext->getBlock())[currentStmtIdx]
+                                                            .getAs<CFGStmt>();
   return CS ? CS->getStmt() : 0;
 }
 
@@ -1033,6 +1036,8 @@ void ExprEngine::processBranch(const Stmt *Condition, const Stmt *Term,
                                ExplodedNodeSet &Dst,
                                const CFGBlock *DstT,
                                const CFGBlock *DstF) {
+  currentBuilderContext = &BldCtx;
+
   // Check for NULL conditions; e.g. "for(;;)"
   if (!Condition) {
     BranchNodeBuilder NullCondBldr(Pred, Dst, BldCtx, DstT, DstF);
@@ -1045,17 +1050,16 @@ void ExprEngine::processBranch(const Stmt *Condition, const Stmt *Term,
                                 Condition->getLocStart(),
                                 "Error evaluating branch");
 
-  ExplodedNodeSet TmpCheckersOut;
-  NodeBuilder CheckerBldr(Pred, TmpCheckersOut, BldCtx);
-  getCheckerManager().runCheckersForBranchCondition(Condition, CheckerBldr,
+  ExplodedNodeSet CheckersOutSet;
+  getCheckerManager().runCheckersForBranchCondition(Condition, CheckersOutSet,
                                                     Pred, *this);
   // We generated only sinks.
-  if (TmpCheckersOut.empty())
+  if (CheckersOutSet.empty())
     return;
 
-  BranchNodeBuilder builder(CheckerBldr.getResults(), Dst, BldCtx, DstT, DstF);
-  for (NodeBuilder::iterator I = CheckerBldr.begin(),
-                             E = CheckerBldr.end(); E != I; ++I) {
+  BranchNodeBuilder builder(CheckersOutSet, Dst, BldCtx, DstT, DstF);
+  for (NodeBuilder::iterator I = CheckersOutSet.begin(),
+                             E = CheckersOutSet.end(); E != I; ++I) {
     ExplodedNode *PredI = *I;
 
     if (PredI->isSink())
@@ -1107,6 +1111,7 @@ void ExprEngine::processBranch(const Stmt *Condition, const Stmt *Term,
         builder.markInfeasible(false);
     }
   }
+  currentBuilderContext = 0;
 }
 
 /// processIndirectGoto - Called by CoreEngine.  Used to generate successor