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

Anna Zaks ganna at apple.com
Wed Oct 26 14:06:22 PDT 2011


Author: zaks
Date: Wed Oct 26 16:06:22 2011
New Revision: 143057

URL: http://llvm.org/viewvc/llvm-project?rev=143057&view=rev
Log:
[analyzer] GenericNodeBuilder -> NodeBuilder.

Remove GenericNodeBuilder and use a class inherited from NodeBuilder instead.

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

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=143057&r1=143056&r2=143057&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h Wed Oct 26 16:06:22 2011
@@ -168,6 +168,7 @@
   void enqueue(ExplodedNodeSet &NB);
 };
 
+// TODO: Turn into a calss.
 struct NodeBuilderContext {
   CoreEngine &Eng;
   const CFGBlock *Block;
@@ -175,6 +176,8 @@
   NodeBuilderContext(CoreEngine &E, const CFGBlock *B, ExplodedNode *N)
     : Eng(E), Block(B), Pred(N) { assert(B); assert(!N->isSink()); }
 
+  ExplodedNode *getPred() const { return Pred; }
+
   /// \brief Return the CFGBlock associated with this builder.
   const CFGBlock *getBlock() const { return Block; }
 
@@ -288,6 +291,34 @@
   void addNodes(ExplodedNode *N) { Frontier.Add(N); }
 };
 
+/// \class NodeBuilderWithSinks
+/// \brief This node builder keeps track of the generated sink nodes.
+class NodeBuilderWithSinks: public NodeBuilder {
+protected:
+  SmallVector<ExplodedNode*, 2> sinksGenerated;
+  ProgramPoint &Location;
+
+public:
+  NodeBuilderWithSinks(ExplodedNode *Pred, ExplodedNodeSet &DstSet,
+                       const NodeBuilderContext &Ctx, ProgramPoint &L)
+    : NodeBuilder(Pred, DstSet, Ctx), Location(L) {}
+  ExplodedNode *generateNode(const ProgramState *State,
+                             ExplodedNode *Pred,
+                             const ProgramPointTag *Tag = 0,
+                             bool MarkAsSink = false) {
+    ProgramPoint LocalLoc = (Tag ? Location.withTag(Tag): Location);
+
+    ExplodedNode *N = generateNodeImpl(LocalLoc, State, Pred, MarkAsSink);
+    if (N && N->isSink())
+      sinksGenerated.push_back(N);
+    return N;
+  }
+
+  const SmallVectorImpl<ExplodedNode*> &getSinks() const {
+    return sinksGenerated;
+  }
+};
+
 /// \class StmtNodeBuilder
 /// \brief This builder class is useful for generating nodes that resulted from
 /// visiting a statement. The main difference from it's parent NodeBuilder is
@@ -467,52 +498,6 @@
   const ProgramState *getState() const { return Pred->State; }
 };
 
-class GenericNodeBuilderImpl {
-protected:
-  CoreEngine &engine;
-  ExplodedNode *pred;
-  ProgramPoint pp;
-  SmallVector<ExplodedNode*, 2> sinksGenerated;  
-
-  ExplodedNode *generateNodeImpl(const ProgramState *state,
-                                 ExplodedNode *pred,
-                                 ProgramPoint programPoint,
-                                 bool asSink);
-
-  GenericNodeBuilderImpl(CoreEngine &eng, ExplodedNode *pr, ProgramPoint p)
-    : engine(eng), pred(pr), pp(p), hasGeneratedNode(false) {}
-
-public:
-  bool hasGeneratedNode;
-  
-  WorkList &getWorkList() { return *engine.WList; }
-  
-  ExplodedNode *getPredecessor() const { return pred; }
-  
-  BlockCounter getBlockCounter() const {
-    return engine.WList->getBlockCounter();
-  }
-  
-  const SmallVectorImpl<ExplodedNode*> &sinks() const {
-    return sinksGenerated;
-  }
-};
-
-template <typename PP_T>
-class GenericNodeBuilder : public GenericNodeBuilderImpl {
-public:
-  GenericNodeBuilder(CoreEngine &eng, ExplodedNode *pr, const PP_T &p)
-    : GenericNodeBuilderImpl(eng, pr, p) {}
-
-  ExplodedNode *generateNode(const ProgramState *state, ExplodedNode *pred,
-                             const ProgramPointTag *tag, bool asSink) {
-    return generateNodeImpl(state, pred, cast<PP_T>(pp).withTag(tag),
-                            asSink);
-  }
-  
-  const PP_T &getProgramPoint() const { return cast<PP_T>(pp); }
-};
-
 class CallEnterNodeBuilder {
   CoreEngine &Eng;
 

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=143057&r1=143056&r2=143057&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h Wed Oct 26 16:06:22 2011
@@ -161,8 +161,7 @@
                             ExplodedNode *Pred, ExplodedNodeSet &Dst);
 
   /// Called by CoreEngine when processing the entrance of a CFGBlock.
-  virtual void processCFGBlockEntrance(ExplodedNodeSet &dstNodes,
-                                GenericNodeBuilder<BlockEntrance> &nodeBuilder);
+  virtual void processCFGBlockEntrance(NodeBuilderWithSinks &nodeBuilder);
   
   /// ProcessBranch - Called by CoreEngine.  Used to generate successor
   ///  nodes by processing the 'effects' of a branch condition.

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=143057&r1=143056&r2=143057&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h Wed Oct 26 16:06:22 2011
@@ -40,6 +40,7 @@
 class EndOfFunctionNodeBuilder;
 class CallEnterNodeBuilder;
 class CallExitNodeBuilder;
+class NodeBuilderWithSinks;
 class MemRegion;
 
 class SubEngine {
@@ -60,8 +61,7 @@
   /// Called by CoreEngine when it starts processing a CFGBlock.  The
   /// SubEngine is expected to populate dstNodes with new nodes representing
   /// updated analysis state, or generate no nodes at all if it doesn't.
-  virtual void processCFGBlockEntrance(ExplodedNodeSet &dstNodes,
-                            GenericNodeBuilder<BlockEntrance> &nodeBuilder) = 0;
+  virtual void processCFGBlockEntrance(NodeBuilderWithSinks &nodeBuilder) = 0;
 
   /// Called by CoreEngine.  Used to generate successor
   ///  nodes by processing the 'effects' of a branch condition.

Modified: cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp?rev=143057&r1=143056&r2=143057&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp Wed Oct 26 16:06:22 2011
@@ -261,6 +261,7 @@
 void CoreEngine::HandleBlockEdge(const BlockEdge &L, ExplodedNode *Pred) {
 
   const CFGBlock *Blk = L.getDst();
+  NodeBuilderContext BuilderCtx(*this, Blk, Pred);
 
   // Check if we are entering the EXIT block.
   if (Blk == &(L.getLocationContext()->getCFG()->getExit())) {
@@ -269,35 +270,30 @@
             && "EXIT block cannot contain Stmts.");
 
     // Process the final state transition.
-    NodeBuilderContext BuilderCtx(*this, Blk, Pred);
     SubEng.processEndOfFunction(BuilderCtx);
 
     // This path is done. Don't enqueue any more nodes.
     return;
   }
 
-  // Call into the subengine to process entering the CFGBlock.
+  // Call into the SubEngine to process entering the CFGBlock.
   ExplodedNodeSet dstNodes;
   BlockEntrance BE(Blk, Pred->getLocationContext());
-  GenericNodeBuilder<BlockEntrance> nodeBuilder(*this, Pred, BE);
-  SubEng.processCFGBlockEntrance(dstNodes, nodeBuilder);
+  NodeBuilderWithSinks nodeBuilder(Pred, dstNodes, BuilderCtx, BE);
+  SubEng.processCFGBlockEntrance(nodeBuilder);
 
-  if (dstNodes.empty()) {
-    if (!nodeBuilder.hasGeneratedNode) {
-      // Auto-generate a node and enqueue it to the worklist.
-      generateNode(BE, Pred->State, Pred);    
-    }
-  }
-  else {
-    for (ExplodedNodeSet::iterator I = dstNodes.begin(), E = dstNodes.end();
-         I != E; ++I) {
-      WList->enqueue(*I);
-    }
+  // Auto-generate a node.
+  if (!nodeBuilder.hasGeneratedNodes()) {
+    nodeBuilder.generateNode(Pred->State, Pred);
   }
 
+  // Enqueue nodes onto the worklist.
+  enqueue(dstNodes);
+
+  // Make sink nodes as exhausted.
+  const SmallVectorImpl<ExplodedNode*> &Sinks =  nodeBuilder.getSinks();
   for (SmallVectorImpl<ExplodedNode*>::const_iterator
-       I = nodeBuilder.sinks().begin(), E = nodeBuilder.sinks().end();
-       I != E; ++I) {
+         I =Sinks.begin(), E = Sinks.end(); I != E; ++I) {
     blocksExhausted.push_back(std::make_pair(L, *I));
   }
 }
@@ -465,27 +461,6 @@
   }
 }
 
-ExplodedNode *
-GenericNodeBuilderImpl::generateNodeImpl(const ProgramState *state,
-                                         ExplodedNode *pred,
-                                         ProgramPoint programPoint,
-                                         bool asSink) {
-  
-  hasGeneratedNode = true;
-  bool isNew;
-  ExplodedNode *node = engine.getGraph().getNode(programPoint, state, &isNew);
-  if (pred)
-    node->addPredecessor(pred, engine.getGraph());
-  if (isNew) {
-    if (asSink) {
-      node->markAsSink();
-      sinksGenerated.push_back(node);
-    }
-    return node;
-  }
-  return 0;
-}
-
 ExplodedNode* NodeBuilder::generateNodeImpl(const ProgramPoint &Loc,
                                             const ProgramState *State,
                                             ExplodedNode *FromN,

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=143057&r1=143056&r2=143057&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Wed Oct 26 16:06:22 2011
@@ -909,20 +909,13 @@
   }
 }
 
-//===----------------------------------------------------------------------===//
-// Block entrance.  (Update counters).
-//===----------------------------------------------------------------------===//
-
-void ExprEngine::processCFGBlockEntrance(ExplodedNodeSet &dstNodes,
-                               GenericNodeBuilder<BlockEntrance> &nodeBuilder){
+/// Block entrance.  (Update counters).
+void ExprEngine::processCFGBlockEntrance(NodeBuilderWithSinks &nodeBuilder) {
   
   // FIXME: Refactor this into a checker.
-  const CFGBlock *block = nodeBuilder.getProgramPoint().getBlock();
-  ExplodedNode *pred = nodeBuilder.getPredecessor();
+  ExplodedNode *pred = nodeBuilder.getContext().getPred();
   
-  if (nodeBuilder.getBlockCounter().getNumVisited(
-                       pred->getLocationContext()->getCurrentStackFrame(), 
-                       block->getBlockID()) >= AMgr.getMaxVisit()) {
+  if (nodeBuilder.getContext().getCurrentBlockCount() >= AMgr.getMaxVisit()) {
     static SimpleProgramPointTag tag("ExprEngine : Block count exceeded");
     nodeBuilder.generateNode(pred->getState(), pred, &tag, true);
   }





More information about the cfe-commits mailing list