[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