[cfe-commits] r142448 - in /cfe/trunk: include/clang/StaticAnalyzer/Core/Checker.h include/clang/StaticAnalyzer/Core/CheckerManager.h include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp lib/StaticAnalyzer/Core/CheckerManager.cpp lib/StaticAnalyzer/Core/CoreEngine.cpp lib/StaticAnalyzer/Core/ExprEngine.cpp

Anna Zaks ganna at apple.com
Tue Oct 18 16:06:21 PDT 2011


Author: zaks
Date: Tue Oct 18 18:06:21 2011
New Revision: 142448

URL: http://llvm.org/viewvc/llvm-project?rev=142448&view=rev
Log:
[analyzer] Modularize builder use in processBranch.

Take advantage of the new builders for branch processing. As part of this change pass generic NodeBuilder (instead of BranchNodeBuilder) to the BranchCondition callback and remove the unused methods form BranchBuilder.

Modified:
    cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h
    cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h
    cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
    cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
    cfe/trunk/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h?rev=142448&r1=142447&r2=142448&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h Tue Oct 18 18:06:21 2011
@@ -215,7 +215,7 @@
 class BranchCondition {
   template <typename CHECKER>
   static void _checkBranchCondition(void *checker, const Stmt *condition,
-                                    BranchNodeBuilder &B, ExprEngine &Eng) {
+                                    NodeBuilder &B, ExprEngine &Eng) {
     ((const CHECKER *)checker)->checkBranchCondition(condition, B, Eng);
   }
 

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h?rev=142448&r1=142447&r2=142448&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h Tue Oct 18 18:06:21 2011
@@ -39,7 +39,7 @@
   class ExplodedGraph;
   class ProgramState;
   class EndOfFunctionNodeBuilder;
-  class BranchNodeBuilder;
+  class NodeBuilder;
   class MemRegion;
   class SymbolReaper;
 
@@ -232,7 +232,7 @@
 
   /// \brief Run checkers for branch condition.
   void runCheckersForBranchCondition(const Stmt *condition,
-                                     BranchNodeBuilder &B, ExprEngine &Eng);
+                                     NodeBuilder &B, ExprEngine &Eng);
 
   /// \brief Run checkers for live symbols.
   ///
@@ -334,7 +334,7 @@
   typedef CheckerFn<void (EndOfFunctionNodeBuilder &, ExprEngine &)>
       CheckEndPathFunc;
   
-  typedef CheckerFn<void (const Stmt *, BranchNodeBuilder &, ExprEngine &)>
+  typedef CheckerFn<void (const Stmt *, NodeBuilder &, ExprEngine &)>
       CheckBranchConditionFunc;
   
   typedef CheckerFn<void (SymbolReaper &, CheckerContext &)>

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h?rev=142448&r1=142447&r2=142448&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h Tue Oct 18 18:06:21 2011
@@ -51,7 +51,7 @@
       ST(st),
       size(Dst.size()),
       Ctx(builder.Eng, builder.getBlock()),
-      NB(Ctx, pred),
+      NB(pred, Ctx),
       respondsToCallback(respondsToCB) {
     assert(!(ST && ST != Pred->getState()));
   }

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h?rev=142448&r1=142447&r2=142448&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h Tue Oct 18 18:06:21 2011
@@ -181,7 +181,7 @@
   friend class StmtNodeBuilder;
 
   ExplodedNode *BuilderPred;
-  NodeBuilderContext &C;
+  const NodeBuilderContext &C;
   bool Finalized;
 
   /// \brief The frontier set - a set of nodes which need to be propagated after
@@ -212,12 +212,19 @@
                                  bool MarkAsSink = false);
 
 public:
-  NodeBuilder(NodeBuilderContext &Ctx, ExplodedNode *N)
+  NodeBuilder(ExplodedNode *N, NodeBuilderContext &Ctx)
     : BuilderPred(N), C(Ctx), Finalized(false) {
     assert(!N->isSink());
     Deferred.insert(N);
   }
 
+  /// Create a new builder using the parent builder's context.
+  NodeBuilder(ExplodedNode *N, const NodeBuilder &ParentBldr)
+    : BuilderPred(N), C(ParentBldr.C), Finalized(false) {
+    assert(!N->isSink());
+    Deferred.insert(N);
+  }
+
   virtual ~NodeBuilder() {}
 
   /// \brief Generates a node in the ExplodedGraph.
@@ -258,7 +265,11 @@
                          C.Block->getBlockID());
   }
 
+  // \brief Get the builder's predecessor - the parent to all the other nodes.
   ExplodedNode *getPredecessor() const { return BuilderPred; }
+
+  // \brief Returns state of the predecessor.
+  const ProgramState *getState() const { return BuilderPred->getState(); }
 };
 
 class CommonNodeBuilder {
@@ -409,19 +420,19 @@
   }
 
 public:
-  BranchNodeBuilder(NodeBuilderContext &C, ExplodedNode *Pred,
+  BranchNodeBuilder(ExplodedNode *Pred, NodeBuilderContext &C,
                     const CFGBlock *dstT, const CFGBlock *dstF)
-  : NodeBuilder(C, Pred), DstT(dstT), DstF(dstF),
+  : NodeBuilder(Pred, C), DstT(dstT), DstF(dstF),
     GeneratedTrue(false), GeneratedFalse(false),
     InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {
   }
 
-  /// This function generate a new ExplodedNode but not a new
-  /// branch(block edge). Creates a transition from the Builder's top
-  /// predecessor.
-  ExplodedNode *generateNode(const Stmt *Condition, const ProgramState *State,
-                             const ProgramPointTag *Tag = 0,
-                             bool MarkAsSink = false);
+  /// Create a new builder using the parent builder's context.
+  BranchNodeBuilder(ExplodedNode *Pred, BranchNodeBuilder &ParentBldr)
+  : NodeBuilder(Pred, ParentBldr), DstT(ParentBldr.DstT), DstF(ParentBldr.DstF),
+    GeneratedTrue(false), GeneratedFalse(false),
+    InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {
+  }
 
   ExplodedNode *generateNode(const ProgramState *State, bool branch,
                              ExplodedNode *Pred = 0);
@@ -440,10 +451,6 @@
   bool isFeasible(bool branch) {
     return branch ? !InFeasibleTrue : !InFeasibleFalse;
   }
-
-  const ProgramState *getState() const {
-    return getPredecessor()->getState();
-  }
 };
 
 class IndirectGotoNodeBuilder {

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp?rev=142448&r1=142447&r2=142448&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp Tue Oct 18 18:06:21 2011
@@ -49,20 +49,27 @@
   };
 
 public:
-  void checkBranchCondition(const Stmt *Condition, BranchNodeBuilder &Builder,
+  void checkBranchCondition(const Stmt *Condition, NodeBuilder &Builder,
                             ExprEngine &Eng) const;
 };
 
 }
 
 void UndefBranchChecker::checkBranchCondition(const Stmt *Condition,
-                                              BranchNodeBuilder &Builder,
+                                              NodeBuilder &Builder,
                                               ExprEngine &Eng) const {
   const ProgramState *state = Builder.getState();
   SVal X = state->getSVal(Condition);
   if (X.isUndef()) {
-    // Generate a sink node.
-    ExplodedNode *N = Builder.generateNode(Condition, state, 0, true);
+    // 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,
+                        Builder.getPredecessor()->getLocationContext(), Tag);
+    // Generate a sink node, which implicitly marks both outgoing branches as
+    // infeasible.
+    ExplodedNode *N = Builder.generateNode(PP, state,
+                                           Builder.getPredecessor(), true);
     if (N) {
       if (!BT)
         BT.reset(
@@ -102,9 +109,6 @@
 
       Eng.getBugReporter().EmitReport(R);
     }
-
-    Builder.markInfeasible(true);
-    Builder.markInfeasible(false);
   }
 }
 

Modified: cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp?rev=142448&r1=142447&r2=142448&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp Tue Oct 18 18:06:21 2011
@@ -297,7 +297,7 @@
 
 /// \brief Run checkers for branch condition.
 void CheckerManager::runCheckersForBranchCondition(const Stmt *condition,
-                                                   BranchNodeBuilder &B,
+                                                   NodeBuilder &B,
                                                    ExprEngine &Eng) {
   for (unsigned i = 0, e = BranchConditionCheckers.size(); i != e; ++i) {
     CheckBranchConditionFunc fn = BranchConditionCheckers[i];

Modified: cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp?rev=142448&r1=142447&r2=142448&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp Tue Oct 18 18:06:21 2011
@@ -602,21 +602,6 @@
   return NULL;
 }
 
-// This function generate a new ExplodedNode but not a new branch(block edge).
-// Creates a transition from the Builder's top predecessor.
-ExplodedNode *BranchNodeBuilder::generateNode(const Stmt *Condition,
-                                              const ProgramState *State,
-                                              const ProgramPointTag *Tag,
-                                              bool MarkAsSink) {
-  ProgramPoint PP = PostCondition(Condition,
-                                  BuilderPred->getLocationContext(), Tag);
-  ExplodedNode *N = generateNodeImpl(PP, State, BuilderPred, MarkAsSink);
-  assert(N);
-  // TODO: This needs to go - we should not change Pred!!!
-  BuilderPred = N;
-  return N;
-}
-
 ExplodedNode *BranchNodeBuilder::generateNode(const ProgramState *State,
                                               bool branch,
                                               ExplodedNode *NodePred) {

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=142448&r1=142447&r2=142448&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Tue Oct 18 18:06:21 2011
@@ -945,11 +945,9 @@
                                const CFGBlock *DstT,
                                const CFGBlock *DstF) {
 
-  BranchNodeBuilder builder(BldCtx, Pred, DstT, DstF);
-
   // Check for NULL conditions; e.g. "for(;;)"
   if (!Condition) {
-    BranchNodeBuilder NullCondBldr(BldCtx, Pred, DstT, DstF);
+    BranchNodeBuilder NullCondBldr(Pred, BldCtx, DstT, DstF);
     NullCondBldr.markInfeasible(false);
     Engine.enqueue(NullCondBldr);
     return;
@@ -959,27 +957,36 @@
                                 Condition->getLocStart(),
                                 "Error evaluating branch");
 
-  //TODO: This should take the NodeBuiolder.
-  getCheckerManager().runCheckersForBranchCondition(Condition, builder,
+  NodeBuilder CheckerBldr(Pred, BldCtx);
+  getCheckerManager().runCheckersForBranchCondition(Condition, CheckerBldr,
                                                     *this);
 
-  const ProgramState *PrevState = builder.getState();
-  SVal X = PrevState->getSVal(Condition);
+  for (NodeBuilder::iterator I = CheckerBldr.results_begin(),
+                             E = CheckerBldr.results_end(); E != I; ++I) {
+    ExplodedNode *PredI = *I;
+
+    if (PredI->isSink())
+      continue;
 
-  if (X.isUnknownOrUndef()) {
-    // Give it a chance to recover from unknown.
-    if (const Expr *Ex = dyn_cast<Expr>(Condition)) {
-      if (Ex->getType()->isIntegerType()) {
-        // Try to recover some path-sensitivity.  Right now casts of symbolic
-        // integers that promote their values are currently not tracked well.
-        // If 'Condition' is such an expression, try and recover the
-        // underlying value and use that instead.
-        SVal recovered = RecoverCastedSymbol(getStateManager(),
-                                             builder.getState(), Condition,
-                                             getContext());
+    BranchNodeBuilder builder(PredI, BldCtx, DstT, DstF);
+    const ProgramState *PrevState = builder.getState();
+    SVal X = PrevState->getSVal(Condition);
+
+    if (X.isUnknownOrUndef()) {
+      // Give it a chance to recover from unknown.
+      if (const Expr *Ex = dyn_cast<Expr>(Condition)) {
+        if (Ex->getType()->isIntegerType()) {
+          // Try to recover some path-sensitivity.  Right now casts of symbolic
+          // integers that promote their values are currently not tracked well.
+          // If 'Condition' is such an expression, try and recover the
+          // underlying value and use that instead.
+          SVal recovered = RecoverCastedSymbol(getStateManager(),
+                                               PrevState, Condition,
+                                               getContext());
 
-        if (!recovered.isUnknown()) {
-          X = recovered;
+          if (!recovered.isUnknown()) {
+            X = recovered;
+          }
         }
       }
     }
@@ -989,30 +996,30 @@
       builder.generateNode(MarkBranch(PrevState, Term, false), false);
       // Enqueue the results into the work list.
       Engine.enqueue(builder);
-      return;
+      continue;
     }
-  }
 
-  DefinedSVal V = cast<DefinedSVal>(X);
+    DefinedSVal V = cast<DefinedSVal>(X);
 
-  // Process the true branch.
-  if (builder.isFeasible(true)) {
-    if (const ProgramState *state = PrevState->assume(V, true))
-      builder.generateNode(MarkBranch(state, Term, true), true);
-    else
-      builder.markInfeasible(true);
-  }
+    // Process the true branch.
+    if (builder.isFeasible(true)) {
+      if (const ProgramState *state = PrevState->assume(V, true))
+        builder.generateNode(MarkBranch(state, Term, true), true);
+      else
+        builder.markInfeasible(true);
+    }
 
-  // Process the false branch.
-  if (builder.isFeasible(false)) {
-    if (const ProgramState *state = PrevState->assume(V, false))
-      builder.generateNode(MarkBranch(state, Term, false), false);
-    else
-      builder.markInfeasible(false);
-  }
+    // Process the false branch.
+    if (builder.isFeasible(false)) {
+      if (const ProgramState *state = PrevState->assume(V, false))
+        builder.generateNode(MarkBranch(state, Term, false), false);
+      else
+        builder.markInfeasible(false);
+    }
 
-  // Enqueue the results into the work list.
-  Engine.enqueue(builder);
+    // Enqueue the results into the work list.
+    Engine.enqueue(builder);
+  }
 }
 
 /// processIndirectGoto - Called by CoreEngine.  Used to generate successor





More information about the cfe-commits mailing list