[cfe-commits] r45722 - in /cfe/trunk: Analysis/ReachabilityEngine.cpp include/clang/Analysis/PathSensitive/ExplodedGraph.h include/clang/Analysis/PathSensitive/ReachabilityEngine.h

Ted Kremenek kremenek at apple.com
Mon Jan 7 13:57:02 PST 2008


Author: kremenek
Date: Mon Jan  7 15:56:52 2008
New Revision: 45722

URL: http://llvm.org/viewvc/llvm-project?rev=45722&view=rev
Log:
Added ownership of "checker state" within the ExplodedGraph. Moved code that
creates the initial root node from the constructor of ReachabilityEngine to
ReachabilityEngine::ExecuteWorklist.


Modified:
    cfe/trunk/Analysis/ReachabilityEngine.cpp
    cfe/trunk/include/clang/Analysis/PathSensitive/ExplodedGraph.h
    cfe/trunk/include/clang/Analysis/PathSensitive/ReachabilityEngine.h

Modified: cfe/trunk/Analysis/ReachabilityEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/ReachabilityEngine.cpp?rev=45722&r1=45721&r2=45722&view=diff

==============================================================================
--- cfe/trunk/Analysis/ReachabilityEngine.cpp (original)
+++ cfe/trunk/Analysis/ReachabilityEngine.cpp Mon Jan  7 15:56:52 2008
@@ -27,29 +27,14 @@
 
 ReachabilityEngineImpl::ReachabilityEngineImpl(CFG& c,
                                                clang::reng::WorkList* wlist)
-  : cfg(c), WList(wlist) {
-    
-  // Get the entry block.  Make sure that it has 1 (and only 1) successor.
-  CFGBlock* Entry = &c.getEntry();  
-  assert (Entry->empty() && "Entry block must be empty.");
-  assert (Entry->succ_size() == 1 && "Entry block must have 1 successor.");
-  
-  // Get the first (and only) successor of Entry.
-  CFGBlock* Succ = *(Entry->succ_begin());
-  
-  // Construct an edge representing the starting location in the function.
-  BlkBlkEdge StartLoc(Entry,Succ);
-  
-  // Create the root node.
-  assert (false && "FIXME soon.");
-//  WList->Enqueue(G->addRoot(getNode(StartLoc));
-}
+  : cfg(c), WList(wlist) {}
 
-void ReachabilityEngineImpl::getNode(const ProgramEdge& Loc, void* State, 
-                                     ExplodedNodeImpl* Pred) {
+ExplodedNodeImpl* ReachabilityEngineImpl::getNode(const ProgramEdge& Loc,
+                                                  void* State, 
+                                                  ExplodedNodeImpl* Pred) {
   
   bool IsNew;
-  ExplodedNodeImpl* V = G->getNodeImpl(Loc,State,IsNew);
+  ExplodedNodeImpl* V = G->getNodeImpl(Loc,State,&IsNew);
 
   // Link the node with its predecessor.
   V->addUntypedPredecessor(Pred);
@@ -72,6 +57,8 @@
       }
     }
   }
+  
+  return V;
 }
 
 void ReachabilityEngineImpl::PopulateParentMap(Stmt* Parent) {
@@ -85,6 +72,23 @@
 }
   
 bool ReachabilityEngineImpl::ExecuteWorkList(unsigned Steps) {
+
+  // Initialize the analysis by constructing the root if none exists.
+  if (G->num_roots() == 0) {
+    // Get the entry block.  Make sure that it has 1 (and only 1) successor.
+    CFGBlock* Entry = &cfg.getEntry();  
+    assert (Entry->empty() && "Entry block must be empty.");
+    assert (Entry->succ_size() == 1 && "Entry block must have 1 successor.");
+    
+    // Get the first (and only) successor of Entry.
+    CFGBlock* Succ = *(Entry->succ_begin());
+    
+    // Construct an edge representing the starting location in the function.
+    BlkBlkEdge StartLoc(Entry,Succ);
+    
+    // Create the root node.
+    WList->Enqueue(G->addRoot(G->getNodeImpl(StartLoc,getInitialState(),NULL)));
+  }
   
   while (Steps && WList->hasWork()) {
     --Steps;

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/ExplodedGraph.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/ExplodedGraph.h?rev=45722&r1=45721&r2=45722&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/ExplodedGraph.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/ExplodedGraph.h Mon Jan  7 15:56:52 2008
@@ -20,6 +20,7 @@
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/Support/Allocator.h"
+#include "llvm/ADT/OwningPtr.h"
 
 namespace clang {
   
@@ -60,13 +61,19 @@
   ///  pair, where 'State' is represented as an opaque void*.  This method
   ///  is intended to be used only by ReachabilityEngineImpl.
   virtual ExplodedNodeImpl* getNodeImpl(const ProgramEdge& L, void* State,
-                                       bool& IsNew) = 0;
+                                       bool* IsNew) = 0;
                                                             
   /// addRoot - Add an untyped node to the set of roots.
-  void addRoot(ExplodedNodeImpl* V) { Roots.push_back(V); }
+  ExplodedNodeImpl* addRoot(ExplodedNodeImpl* V) {
+    Roots.push_back(V);
+    return V;
+  }
 
   /// addEndOfPath - Add an untyped node to the set of EOP nodes.
-  void addEndOfPath(ExplodedNodeImpl* V) { EndNodes.push_back(V); }
+  ExplodedNodeImpl* addEndOfPath(ExplodedNodeImpl* V) {
+    EndNodes.push_back(V);
+    return V;
+  }
 
 public:
   virtual ~ExplodedGraphImpl() {};
@@ -76,16 +83,20 @@
   unsigned getCounter() const { return NodeCounter; }
 };
   
-template <typename STATE>
+template <typename CHECKER>
 class ExplodedGraph : public ExplodedGraphImpl {
 public:
-  typedef STATE                  StateTy;
-  typedef ExplodedNode<StateTy>  NodeTy;
+  typedef CHECKER                     CheckerTy;
+  typedef typename CHECKER::StateTy   StateTy;
+  typedef ExplodedNode<StateTy>       NodeTy;
+  
+protected:
+  llvm::OwningPtr<CheckerTy> CheckerState;
   
 protected:
   virtual ExplodedNodeImpl*
-  getNodeImpl(const ProgramEdge& L, void* State, bool& IsNew) {
-    return getNode(L,ReachabilityTrait<StateTy>::toState(State),&IsNew);
+  getNodeImpl(const ProgramEdge& L, void* State, bool* IsNew) {
+    return getNode(L,ReachabilityTrait<StateTy>::toState(State),IsNew);
   }
     
 public:
@@ -97,6 +108,11 @@
       delete reinterpret_cast<llvm::FoldingSet<NodeTy>*>(I->second);
   }
   
+  /// getCheckerState - Returns the internal checker state associated
+  ///  with the exploded graph.  Ownership remains with the ExplodedGraph
+  ///  objecct.
+  CheckerTy* getCheckerState() const { return CheckerState.get(); }
+  
   /// getNode - Retrieve the node associated with a (Location,State) pair,
   ///  where the 'Location' is a ProgramEdge in the CFG.  If no node for
   ///  this pair exists, it is created.  IsNew is set to true if

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/ReachabilityEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/ReachabilityEngine.h?rev=45722&r1=45721&r2=45722&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/ReachabilityEngine.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/ReachabilityEngine.h Mon Jan  7 15:56:52 2008
@@ -78,14 +78,22 @@
   // Internal methods. 
   
   /// getNode - Implemented by ReachabilityEngine<> subclass. 
-  ///   Creates/fetches a node and inserts it into the graph.
-  virtual void getNode(const ProgramEdge& Loc, void* State,
-                         ExplodedNodeImpl* Pred);
+  ///   Creates/fetches a node and inserts it into the 
+  ExplodedNodeImpl* getNode(const ProgramEdge& Loc, void* State,
+                            ExplodedNodeImpl* Pred);
   
-  inline void getNode(const ProgramEdge& Loc, ExplodedNodeImpl* Pred) {
-    getNode(Loc,Pred->State,Pred);
+  inline ExplodedNodeImpl* getNode(const ProgramEdge& Loc,
+                                   ExplodedNodeImpl* Pred) {
+    
+    return getNode(Loc,Pred->State,Pred);
   }
   
+  /// getInitialState - Gets the void* representing the initial 'state'
+  ///  of the analysis.  This is simply a wrapper (implemented
+  ///  in ReachabilityEngine) that performs type erasure on the initial
+  ///  state returned by the checker object.
+  virtual void* getInitialState() = 0;
+  
   /// PopulateParentMap - Populates ParentMap starting from the specified
   ///   expression.
   void PopulateParentMap(Stmt* Parent);  
@@ -117,13 +125,17 @@
 template<typename CHECKER>
 class ReachabilityEngine : public ReachabilityEngineImpl {
 public:
-  typedef CHECKER                                CheckerTy;   
+  typedef CHECKER                                CheckerTy; 
   typedef typename CheckerTy::StateTy            StateTy;
-  typedef typename CheckerTy::StateManagerTy     StateManagerTy;
-  typedef ExplodedGraph<StateTy>                 GraphTy;
+  typedef ExplodedGraph<CheckerTy>               GraphTy;
   typedef typename GraphTy::NodeTy               NodeTy;
 
 protected:
+
+  virtual void* getInitialState() {
+    return (void*) getCheckerState()->getInitialState();        
+  }
+  
   virtual void ProcessEOP(CFGBlock* Blk, ExplodedNodeImpl* Pred) {
     assert (false && "Not implemented yet.");
     // FIXME: Perform dispatch to adjust state.
@@ -162,9 +174,15 @@
   ///  with the ReachabilityEngine object.
   GraphTy* getGraph() const { return static_cast<GraphTy*>(G.get()); }
   
-  /// takeGraph - Returns the exploded graph.  Ownership of the graph is
+  /// getCheckerState - Returns the internal checker state.  Ownership is not
   ///  transferred to the caller.
-  GraphTy* takeGraph() { return static_cast<GraphTy*>(G.take()); }  
+  CheckerTy* getCheckerState() const {
+    return static_cast<GraphTy*>(G.get())->getCheckerState();
+  }  
+  
+  /// takeGraph - Returns the exploded graph.  Ownership of the graph is
+  ///  transfered to the caller.
+  GraphTy* takeGraph() { return static_cast<GraphTy*>(G.take()); }
 };
 
 } // end clang namespace





More information about the cfe-commits mailing list