[cfe-commits] r142826 - in /cfe/trunk: include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h lib/StaticAnalyzer/Core/CheckerContext.cpp lib/StaticAnalyzer/Core/CoreEngine.cpp lib/StaticAnalyzer/Core/ExprEngine.cpp

Anna Zaks ganna at apple.com
Mon Oct 24 11:25:53 PDT 2011


Author: zaks
Date: Mon Oct 24 13:25:53 2011
New Revision: 142826

URL: http://llvm.org/viewvc/llvm-project?rev=142826&view=rev
Log:
[analyzer] Pass external Dst set to NodeBuilder

This moves the responsibility for storing the output node set from the
builder to the clients. The builder is just responsible for transforming
an input set into the output set: {SrcSet/SrcNode} -> {Frontier}.

Modified:
    cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
    cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
    cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
    cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
    cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
    cfe/trunk/lib/StaticAnalyzer/Core/CheckerContext.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp

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=142826&r1=142825&r2=142826&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h Mon Oct 24 13:25:53 2011
@@ -29,8 +29,6 @@
   const ProgramPoint Location;
   const ProgramState *ST;
   const unsigned size;
-  // TODO: Use global context.
-  NodeBuilderContext Ctx;
   NodeBuilder &NB;
 public:
   bool *respondsToCallback;
@@ -48,7 +46,6 @@
       Location(loc),
       ST(st),
       size(Dst.size()),
-      Ctx(builder.C.Eng, builder.getBlock(), pred),
       NB(builder),
       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=142826&r1=142825&r2=142826&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h Mon Oct 24 13:25:53 2011
@@ -165,7 +165,7 @@
   }
 
   /// Enqueue the results of the node builder onto the work list.
-  void enqueue(NodeBuilder &NB);
+  void enqueue(ExplodedNodeSet &NB);
 };
 
 struct NodeBuilderContext {
@@ -181,12 +181,7 @@
 protected:
   friend class StmtNodeBuilder;
 
-  ExplodedNode *BuilderPred;
-
-// TODO: Context should become protected after refactoring is done.
-public:
   const NodeBuilderContext &C;
-protected:
 
   /// Specifies if the builder results have been finalized. For example, if it
   /// is set to false, autotransitions are yet to be generated.
@@ -196,8 +191,7 @@
 
   /// \brief The frontier set - a set of nodes which need to be propagated after
   /// the builder dies.
-  typedef llvm::SmallPtrSet<ExplodedNode*,5> DeferredTy;
-  DeferredTy Deferred;
+  ExplodedNodeSet &Frontier;
 
   BlockCounter getBlockCounter() const { return C.Eng.WList->getBlockCounter();}
 
@@ -205,9 +199,6 @@
   virtual bool checkResults() {
     if (!Finalized)
       return false;
-    for (DeferredTy::iterator I=Deferred.begin(), E=Deferred.end(); I!=E; ++I)
-      if ((*I)->isSink())
-        return false;
     return true;
   }
 
@@ -220,15 +211,16 @@
                                  bool MarkAsSink = false);
 
 public:
-  NodeBuilder(NodeBuilderContext &Ctx, bool F = true)
-    : C(Ctx), Finalized(F), HasGeneratedNodes(false) {
-    Deferred.insert(C.ContextPred);
+  NodeBuilder(ExplodedNode *SrcNode, ExplodedNodeSet &DstSet,
+              const NodeBuilderContext &Ctx, bool F = true)
+    : C(Ctx), Finalized(F), HasGeneratedNodes(false), Frontier(DstSet) {
+    Frontier.insert(SrcNode);
   }
 
-  /// Create a new builder using the parent builder's context.
-  NodeBuilder(const NodeBuilder &ParentBldr, bool F = true)
-    : C(ParentBldr.C), Finalized(F), HasGeneratedNodes(false) {
-    Deferred.insert(C.ContextPred);
+  NodeBuilder(const ExplodedNodeSet &SrcSet, ExplodedNodeSet &DstSet,
+              const NodeBuilderContext &Ctx, bool F = true)
+    : C(Ctx), Finalized(F), HasGeneratedNodes(false), Frontier(DstSet) {
+    Frontier.insert(SrcSet);
   }
 
   virtual ~NodeBuilder() {}
@@ -249,21 +241,29 @@
     return HasGeneratedNodes;
   }
 
-  typedef DeferredTy::iterator iterator;
+  const ExplodedNodeSet &getResults() {
+    finalizeResults();
+    assert(checkResults());
+    return Frontier;
+  }
+
+  typedef ExplodedNodeSet::iterator iterator;
   /// \brief Iterators through the results frontier.
-  inline iterator results_begin() {
+  inline iterator begin() {
     finalizeResults();
     assert(checkResults());
-    return Deferred.begin();
+    return Frontier.begin();
   }
-  inline iterator results_end() {
+  inline iterator end() {
     finalizeResults();
-    return Deferred.end();
+    return Frontier.end();
   }
 
   /// \brief Return the CFGBlock associated with this builder.
   const CFGBlock *getBlock() const { return C.Block; }
 
+  const NodeBuilderContext &getContext() { return C; }
+
   /// \brief Returns the number of times the current basic block has been
   /// visited on the exploded graph path.
   unsigned getCurrentBlockCount() const {
@@ -297,7 +297,11 @@
   void GenerateAutoTransition(ExplodedNode *N);
 
 public:
-  StmtNodeBuilder(ExplodedNode *N, unsigned idx, NodeBuilderContext &Ctx);
+  StmtNodeBuilder(ExplodedNode *SrcNode, ExplodedNodeSet &DstSet,
+                  unsigned idx, const NodeBuilderContext &Ctx)
+    : NodeBuilder(SrcNode, DstSet, Ctx), Idx(idx),
+      PurgingDeadSymbols(false), BuildSinks(false), hasGeneratedNode(false),
+      PointKind(ProgramPoint::PostStmtKind), Tag(0) {}
 
   ~StmtNodeBuilder();
   
@@ -364,8 +368,8 @@
   void importNodesFromBuilder(const NodeBuilder &NB) {
     ExplodedNode *NBPred = const_cast<ExplodedNode*>(NB.C.ContextPred);
     if (NB.hasGeneratedNodes()) {
-      Deferred.erase(NBPred);
-      Deferred.insert(NB.Deferred.begin(), NB.Deferred.end());
+      Frontier.erase(NBPred);
+      Frontier.insert(NB.Frontier);
     }
   }
 };
@@ -378,15 +382,16 @@
   bool InFeasibleFalse;
 
 public:
-  BranchNodeBuilder(NodeBuilderContext &C,
+  BranchNodeBuilder(ExplodedNode *SrcNode, ExplodedNodeSet &DstSet,
+                    const NodeBuilderContext &C,
                     const CFGBlock *dstT, const CFGBlock *dstF)
-  : NodeBuilder(C), DstT(dstT), DstF(dstF),
+  : NodeBuilder(SrcNode, DstSet, C), DstT(dstT), DstF(dstF),
     InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {}
 
-  /// Create a new builder using the parent builder's context.
-  BranchNodeBuilder(BranchNodeBuilder &ParentBldr)
-  : NodeBuilder(ParentBldr), DstT(ParentBldr.DstT),
-    DstF(ParentBldr.DstF),
+  BranchNodeBuilder(const ExplodedNodeSet &SrcSet, ExplodedNodeSet &DstSet,
+                    const NodeBuilderContext &C,
+                    const CFGBlock *dstT, const CFGBlock *dstF)
+  : NodeBuilder(SrcSet, DstSet, C), DstT(dstT), DstF(dstF),
     InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {}
 
   ExplodedNode *generateNode(const ProgramState *State, bool branch,

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h?rev=142826&r1=142825&r2=142826&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h Mon Oct 24 13:25:53 2011
@@ -386,6 +386,7 @@
 
   unsigned size() const { return Impl.size();  }
   bool empty()    const { return Impl.empty(); }
+  bool erase(ExplodedNode *N) { return Impl.erase(N); }
 
   void clear() { Impl.clear(); }
   void insert(const ExplodedNodeSet &S) {

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h?rev=142826&r1=142825&r2=142826&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h Mon Oct 24 13:25:53 2011
@@ -117,6 +117,10 @@
   BugReporter& getBugReporter() { return BR; }
 
   StmtNodeBuilder &getBuilder() { assert(Builder); return *Builder; }
+  const NodeBuilderContext &getBuilderContext() {
+    assert(Builder);
+    return Builder->getContext();
+  }
 
   bool isObjCGCEnabled() { return ObjCGCEnabled; }
 
@@ -163,6 +167,7 @@
   void processBranch(const Stmt *Condition, const Stmt *Term, 
                      NodeBuilderContext& BuilderCtx,
                      ExplodedNode *Pred,
+                     ExplodedNodeSet &Dst,
                      const CFGBlock *DstT,
                      const CFGBlock *DstF);
 

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h?rev=142826&r1=142825&r2=142826&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h Mon Oct 24 13:25:53 2011
@@ -69,6 +69,7 @@
   virtual void processBranch(const Stmt *Condition, const Stmt *Term,
                              NodeBuilderContext& BuilderCtx,
                              ExplodedNode *Pred,
+                             ExplodedNodeSet &Dst,
                              const CFGBlock *DstT,
                              const CFGBlock *DstF) = 0;
 

Modified: cfe/trunk/lib/StaticAnalyzer/Core/CheckerContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CheckerContext.cpp?rev=142826&r1=142825&r2=142826&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CheckerContext.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CheckerContext.cpp Mon Oct 24 13:25:53 2011
@@ -18,8 +18,8 @@
 
 CheckerContext::~CheckerContext() {
   // Copy the results into the Dst set.
-  for (NodeBuilder::iterator I = NB.results_begin(),
-                             E = NB.results_end(); I != E; ++I) {
+  for (NodeBuilder::iterator I = NB.begin(),
+                             E = NB.end(); I != E; ++I) {
     Dst.Add(*I);
   }
 }

Modified: cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp?rev=142826&r1=142825&r2=142826&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp Mon Oct 24 13:25:53 2011
@@ -315,7 +315,8 @@
   // Process the entrance of the block.
   if (CFGElement E = L.getFirstElement()) {
     NodeBuilderContext Ctx(*this, L.getBlock(), Pred);
-    StmtNodeBuilder Builder(Pred, 0, Ctx);
+    ExplodedNodeSet Dst;
+    StmtNodeBuilder Builder(Pred, Dst, 0, Ctx);
     SubEng.processCFGElement(E, Builder, Pred);
   }
   else
@@ -419,8 +420,11 @@
                                 const CFGBlock * B, ExplodedNode *Pred) {
   assert(B->succ_size() == 2);
   NodeBuilderContext Ctx(*this, B, Pred);
-  SubEng.processBranch(Cond, Term, Ctx, Pred,
+  ExplodedNodeSet Dst;
+  SubEng.processBranch(Cond, Term, Ctx, Pred, Dst,
                        *(B->succ_begin()), *(B->succ_begin()+1));
+  // Enqueue the new frontier onto the worklist.
+  enqueue(Dst);
 }
 
 void CoreEngine::HandlePostStmt(const CFGBlock *B, unsigned StmtIdx, 
@@ -432,7 +436,8 @@
     HandleBlockExit(B, Pred);
   else {
     NodeBuilderContext Ctx(*this, B, Pred);
-    StmtNodeBuilder Builder(Pred, StmtIdx, Ctx);
+    ExplodedNodeSet Dst;
+    StmtNodeBuilder Builder(Pred, Dst, StmtIdx, Ctx);
     SubEng.processCFGElement((*B)[StmtIdx], Builder, Pred);
   }
 }
@@ -457,9 +462,9 @@
   if (IsNew) WList->enqueue(Node);
 }
 
-void CoreEngine::enqueue(NodeBuilder &NB) {
-  for (NodeBuilder::iterator I = NB.results_begin(),
-                               E = NB.results_end(); I != E; ++I) {
+void CoreEngine::enqueue(ExplodedNodeSet &S) {
+  for (ExplodedNodeSet::iterator I = S.begin(),
+                                 E = S.end(); I != E; ++I) {
     WList->enqueue(*I);
   }
 }
@@ -494,28 +499,19 @@
   bool IsNew;
   ExplodedNode *N = C.Eng.G->getNode(Loc, State, &IsNew);
   N->addPredecessor(FromN, *C.Eng.G);
-  Deferred.erase(FromN);
+  Frontier.erase(FromN);
 
   if (MarkAsSink)
     N->markAsSink();
-
-  if (IsNew && !N->isSink())
-    Deferred.insert(N);
+    
+  if (IsNew)
+    Frontier.Add(N);
 
   return (IsNew ? N : 0);
 }
 
-
-StmtNodeBuilder::StmtNodeBuilder(ExplodedNode *N, unsigned idx,
-                                 NodeBuilderContext &Ctx)
-  : NodeBuilder(Ctx), Idx(idx),
-    PurgingDeadSymbols(false), BuildSinks(false), hasGeneratedNode(false),
-    PointKind(ProgramPoint::PostStmtKind), Tag(0) {
-  Deferred.insert(N);
-}
-
 StmtNodeBuilder::~StmtNodeBuilder() {
-  for (DeferredTy::iterator I=Deferred.begin(), E=Deferred.end(); I!=E; ++I)
+  for (iterator I=Frontier.begin(), E=Frontier.end(); I!=E; ++I)
     if (!(*I)->isSink())
       GenerateAutoTransition(*I);
 }
@@ -554,14 +550,14 @@
     C.Eng.WList->enqueue(Succ, C.Block, Idx+1);
 }
 
-ExplodedNode *StmtNodeBuilder::MakeNode(ExplodedNodeSet &Dst,
+ExplodedNode *StmtNodeBuilder::MakeNode(ExplodedNodeSet &DstSet,
                                         const Stmt *S, 
                                         ExplodedNode *Pred,
                                         const ProgramState *St,
                                         ProgramPoint::Kind K) {
   ExplodedNode *N = generateNode(S, St, Pred, K, 0, BuildSinks);
   if (N && !BuildSinks){
-      Dst.Add(N);
+      DstSet.Add(N);
   }
   return N;
 }

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=142826&r1=142825&r2=142826&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Mon Oct 24 13:25:53 2011
@@ -945,15 +945,14 @@
 void ExprEngine::processBranch(const Stmt *Condition, const Stmt *Term,
                                NodeBuilderContext& BldCtx,
                                ExplodedNode *Pred,
+                               ExplodedNodeSet &Dst,
                                const CFGBlock *DstT,
                                const CFGBlock *DstF) {
-
   // Check for NULL conditions; e.g. "for(;;)"
   if (!Condition) {
-    BranchNodeBuilder NullCondBldr(BldCtx, DstT, DstF);
+    BranchNodeBuilder NullCondBldr(Pred, Dst, BldCtx, DstT, DstF);
     NullCondBldr.markInfeasible(false);
     NullCondBldr.generateNode(Pred->getState(), true, Pred);
-    Engine.enqueue(NullCondBldr);
     return;
   }
 
@@ -961,18 +960,19 @@
                                 Condition->getLocStart(),
                                 "Error evaluating branch");
 
-  NodeBuilder CheckerBldr(BldCtx);
+  ExplodedNodeSet TmpCheckersOut;
+  NodeBuilder CheckerBldr(Pred, TmpCheckersOut, BldCtx);
   getCheckerManager().runCheckersForBranchCondition(Condition, CheckerBldr,
                                                     Pred, *this);
 
-  for (NodeBuilder::iterator I = CheckerBldr.results_begin(),
-                             E = CheckerBldr.results_end(); E != I; ++I) {
+  BranchNodeBuilder builder(CheckerBldr.getResults(), Dst, BldCtx, DstT, DstF);
+  for (NodeBuilder::iterator I = CheckerBldr.begin(),
+                             E = CheckerBldr.end(); E != I; ++I) {
     ExplodedNode *PredI = *I;
 
     if (PredI->isSink())
       continue;
 
-    BranchNodeBuilder builder(BldCtx, DstT, DstF);
     const ProgramState *PrevState = Pred->getState();
     SVal X = PrevState->getSVal(Condition);
 
@@ -998,8 +998,6 @@
     if (X.isUnknownOrUndef()) {
       builder.generateNode(MarkBranch(PrevState, Term, true), true, PredI);
       builder.generateNode(MarkBranch(PrevState, Term, false), false, PredI);
-      // Enqueue the results into the work list.
-      Engine.enqueue(builder);
       continue;
     }
 
@@ -1020,9 +1018,6 @@
       else
         builder.markInfeasible(false);
     }
-
-    // Enqueue the results into the work list.
-    Engine.enqueue(builder);
   }
 }
 





More information about the cfe-commits mailing list