[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