[cfe-commits] r46532 - in /cfe/trunk: Analysis/GRConstants.cpp Analysis/GREngine.cpp include/clang/Analysis/PathSensitive/ExplodedGraph.h include/clang/Analysis/PathSensitive/GREngine.h
Ted Kremenek
kremenek at apple.com
Tue Jan 29 14:56:11 PST 2008
Author: kremenek
Date: Tue Jan 29 16:56:11 2008
New Revision: 46532
URL: http://llvm.org/viewvc/llvm-project?rev=46532&view=rev
Log:
Added boilerplate logic in GREngine for processing branches.
Modified:
cfe/trunk/Analysis/GRConstants.cpp
cfe/trunk/Analysis/GREngine.cpp
cfe/trunk/include/clang/Analysis/PathSensitive/ExplodedGraph.h
cfe/trunk/include/clang/Analysis/PathSensitive/GREngine.h
Modified: cfe/trunk/Analysis/GRConstants.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/GRConstants.cpp?rev=46532&r1=46531&r2=46532&view=diff
==============================================================================
--- cfe/trunk/Analysis/GRConstants.cpp (original)
+++ cfe/trunk/Analysis/GRConstants.cpp Tue Jan 29 16:56:11 2008
@@ -730,7 +730,8 @@
public:
typedef ValueMapTy StateTy;
- typedef GRStmtNodeBuilder<GRConstants> NodeBuilder;
+ typedef GRStmtNodeBuilder<GRConstants> StmtNodeBuilder;
+ typedef GRBranchNodeBuilder<GRConstants> BranchNodeBuilder;
typedef ExplodedGraph<GRConstants> GraphTy;
typedef GraphTy::NodeTy NodeTy;
@@ -767,8 +768,8 @@
/// Builder - The current GRStmtNodeBuilder which is used when building the nodes
/// for a given statement.
- NodeBuilder* Builder;
-
+ StmtNodeBuilder* Builder;
+
/// StateMgr - Object that manages the data for all created states.
ValueMapTy::Factory StateMgr;
@@ -826,7 +827,12 @@
/// ProcessStmt - Called by GREngine. Used to generate new successor
/// nodes by processing the 'effects' of a block-level statement.
- void ProcessStmt(Stmt* S, NodeBuilder& builder);
+ void ProcessStmt(Stmt* S, StmtNodeBuilder& builder);
+
+ /// ProcessBranch - Called by GREngine. Used to generate successor
+ /// nodes by processing the 'effects' of a branch condition.
+ void ProcessBranch(Stmt* Condition, Stmt* Term, BranchNodeBuilder& builder)
+ {}
/// RemoveDeadBindings - Return a new state that is the same as 'M' except
/// that all subexpression mappings are removed and that any
@@ -871,7 +877,7 @@
} // end anonymous namespace
-void GRConstants::ProcessStmt(Stmt* S, NodeBuilder& builder) {
+void GRConstants::ProcessStmt(Stmt* S, StmtNodeBuilder& builder) {
Builder = &builder;
StmtEntryNode = builder.getLastNode();
Modified: cfe/trunk/Analysis/GREngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/GREngine.cpp?rev=46532&r1=46531&r2=46532&view=diff
==============================================================================
--- cfe/trunk/Analysis/GREngine.cpp (original)
+++ cfe/trunk/Analysis/GREngine.cpp Tue Jan 29 16:56:11 2008
@@ -149,8 +149,29 @@
void GREngineImpl::HandleBlockExit(CFGBlock * B, ExplodedNodeImpl* Pred) {
- if (Stmt* Terminator = B->getTerminator())
- ProcessTerminator(Terminator, B, Pred);
+ if (Stmt* Term = B->getTerminator()) {
+ switch (Term->getStmtClass()) {
+ default:
+ assert(false && "Analysis for this terminator not implemented.");
+ break;
+
+ case Stmt::IfStmtClass:
+ HandleBranch(cast<IfStmt>(Term)->getCond(), Term, B, Pred);
+ break;
+
+ case Stmt::ForStmtClass:
+ HandleBranch(cast<ForStmt>(Term)->getCond(), Term, B, Pred);
+ break;
+
+ case Stmt::WhileStmtClass:
+ HandleBranch(cast<WhileStmt>(Term)->getCond(), Term, B, Pred);
+ break;
+
+ case Stmt::DoStmtClass:
+ HandleBranch(cast<DoStmt>(Term)->getCond(), Term, B, Pred);
+ break;
+ }
+ }
else {
assert (B->succ_size() == 1 &&
"Blocks with no terminator should have at most 1 successor.");
@@ -159,6 +180,16 @@
}
}
+void GREngineImpl::HandleBranch(Stmt* Cond, Stmt* Term, CFGBlock * B,
+ ExplodedNodeImpl* Pred) {
+ assert (B->succ_size() == 2);
+
+ GRBranchNodeBuilderImpl Builder(B, *(B->succ_begin()), *(B->succ_begin()+1),
+ Pred, this);
+
+ ProcessBranch(Cond, Term, Builder);
+}
+
void GREngineImpl::HandlePostStmt(const PostStmt& L, CFGBlock* B,
unsigned StmtIdx, ExplodedNodeImpl* Pred) {
@@ -255,3 +286,16 @@
LastNode = NULL;
return NULL;
}
+
+void GRBranchNodeBuilderImpl::generateNodeImpl(void* State, bool branch) {
+ bool IsNew;
+
+ ExplodedNodeImpl* Succ =
+ Eng.G->getNodeImpl(BlockEdge(Eng.getCFG(), Src, branch ? DstT : DstF),
+ State, &IsNew);
+
+ Succ->addPredecessor(Pred);
+
+ if (IsNew)
+ Eng.WList->Enqueue(GRWorkListUnit(Succ));
+}
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=46532&r1=46531&r2=46532&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/ExplodedGraph.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/ExplodedGraph.h Tue Jan 29 16:56:11 2008
@@ -29,6 +29,7 @@
class GREngineImpl;
class ExplodedNodeImpl;
class GRStmtNodeBuilderImpl;
+class GRBranchNodeBuilderImpl;
class CFG;
class ASTContext;
class FunctionDecl;
@@ -39,6 +40,7 @@
friend class ExplodedGraphImpl;
friend class GREngineImpl;
friend class GRStmtNodeBuilderImpl;
+ friend class GRBranchNodeBuilderImpl;
class NodeGroup {
enum { Size1 = 0x0, SizeOther = 0x1, Infeasible = 0x2, Flags = 0x3 };
@@ -193,6 +195,7 @@
protected:
friend class GREngineImpl;
friend class GRStmtNodeBuilderImpl;
+ friend class GRBranchNodeBuilderImpl;
// Type definitions.
typedef llvm::DenseMap<ProgramPoint,void*> EdgeNodeSetMap;
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GREngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GREngine.h?rev=46532&r1=46531&r2=46532&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GREngine.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GREngine.h Tue Jan 29 16:56:11 2008
@@ -22,11 +22,13 @@
namespace clang {
class GRStmtNodeBuilderImpl;
+class GRBranchNodeBuilderImpl;
class GRWorkList;
class GREngineImpl {
protected:
friend class GRStmtNodeBuilderImpl;
+ friend class GRBranchNodeBuilderImpl;
typedef llvm::DenseMap<Stmt*,Stmt*> ParentMapTy;
@@ -59,13 +61,17 @@
void HandleBlockExit(CFGBlock* B, ExplodedNodeImpl* Pred);
void HandlePostStmt(const PostStmt& S, CFGBlock* B,
unsigned StmtIdx, ExplodedNodeImpl *Pred);
-
+
+ void HandleBranch(Stmt* Cond, Stmt* Term, CFGBlock* B,
+ ExplodedNodeImpl* Pred);
+
virtual void* ProcessEOP(CFGBlock* Blk, void* State) = 0;
- virtual void ProcessStmt(Stmt* S, GRStmtNodeBuilderImpl& Builder) = 0;
+ virtual void ProcessStmt(Stmt* S, GRStmtNodeBuilderImpl& Builder) = 0;
+
+ virtual void ProcessBranch(Stmt* Condition, Stmt* Terminator,
+ GRBranchNodeBuilderImpl& Builder) = 0;
- virtual void ProcessTerminator(Stmt* Terminator, CFGBlock* B,
- ExplodedNodeImpl* Pred) = 0;
private:
GREngineImpl(const GREngineImpl&); // Do not implement.
@@ -154,6 +160,47 @@
}
};
+class GRBranchNodeBuilderImpl {
+ GREngineImpl& Eng;
+ CFGBlock* Src;
+ CFGBlock* DstT;
+ CFGBlock* DstF;
+ ExplodedNodeImpl* Pred;
+
+public:
+ GRBranchNodeBuilderImpl(CFGBlock* src, CFGBlock* dstT, CFGBlock* dstF,
+ ExplodedNodeImpl* pred, GREngineImpl* e)
+ : Eng(*e), Src(src), DstT(dstT), DstF(dstF), Pred(pred) {}
+
+ ~GRBranchNodeBuilderImpl() {}
+
+ const ExplodedGraphImpl& getGraph() const { return *Eng.G; }
+
+ void generateNodeImpl(void* State, bool branch);
+};
+
+template<typename CHECKER>
+class GRBranchNodeBuilder {
+ typedef CHECKER CheckerTy;
+ typedef typename CheckerTy::StateTy StateTy;
+ typedef ExplodedGraph<CheckerTy> GraphTy;
+ typedef typename GraphTy::NodeTy NodeTy;
+
+ GRBranchNodeBuilderImpl& NB;
+
+public:
+ GRBranchNodeBuilder(GRBranchNodeBuilderImpl& nb) : NB(nb) {}
+
+ const GraphTy& getGraph() const {
+ return static_cast<const GraphTy&>(NB.getGraph());
+ }
+
+ void generateNode(StateTy State, bool branch) {
+ void *state = GRTrait<StateTy>::toPtr(State);
+ NB.generateNodeImpl(state, branch);
+ }
+};
+
template<typename CHECKER>
class GREngine : public GREngineImpl {
@@ -182,9 +229,11 @@
Checker->ProcessStmt(S, Builder);
}
- virtual void ProcessTerminator(Stmt* Terminator, CFGBlock* B,
- ExplodedNodeImpl* Pred) {
- // FIXME: Dispatch.
+
+ virtual void ProcessBranch(Stmt* Condition, Stmt* Terminator,
+ GRBranchNodeBuilderImpl& BuilderImpl) {
+ GRBranchNodeBuilder<CHECKER> Builder(BuilderImpl);
+ Checker->ProcessBranch(Condition, Terminator, Builder);
}
More information about the cfe-commits
mailing list