]> granicus.if.org Git - clang/commitdiff
More edge-case handling with using liveness information to prune dead state values.
authorTed Kremenek <kremenek@apple.com>
Mon, 10 Mar 2008 04:45:00 +0000 (04:45 +0000)
committerTed Kremenek <kremenek@apple.com>
Mon, 10 Mar 2008 04:45:00 +0000 (04:45 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@48127 91177308-0d34-0410-b5e6-96231b3b80d8

Analysis/GRCoreEngine.cpp
Analysis/GRExprEngine.cpp
include/clang/Analysis/PathSensitive/GRCoreEngine.h

index cff33373cffaa645c9f0f287530e315b8068f57d..53831ed06d59fb60893443ed74257d617b2a1d05 100644 (file)
@@ -292,7 +292,7 @@ void GRCoreEngineImpl::GenerateNode(const ProgramPoint& Loc, void* State,
 
 GRStmtNodeBuilderImpl::GRStmtNodeBuilderImpl(CFGBlock* b, unsigned idx,
                                      ExplodedNodeImpl* N, GRCoreEngineImpl* e)
-  : Eng(*e), B(*b), Idx(idx), LastNode(N), Populated(false) {
+  : Eng(*e), B(*b), Idx(idx), Pred(N), LastNode(N), Populated(false) {
   Deferred.insert(N);
 }
 
index aafc735c9aba293f9ff38ac02d11762781455e6f..15fe88ec1c1bf8c4e5c0e1e1a8883caf60b20e77 100644 (file)
@@ -403,6 +403,8 @@ void GRExprEngine::ProcessStmt(Stmt* S, StmtNodeBuilder& builder) {
 
   CleanedState = StateMgr.RemoveDeadBindings(StmtEntryNode->getState(),
                                              CurrentStmt, Liveness);
+  
+  Builder->SetCleanedState(CleanedState);
 
   // Visit the statement.
 
index 37dddea281614285101eed21867022c7171c979f..9a8be4e0fd4fdad8d5c594c52c37073b317e7627 100644 (file)
@@ -121,6 +121,7 @@ class GRStmtNodeBuilderImpl {
   GRCoreEngineImpl& Eng;
   CFGBlock& B;
   const unsigned Idx;
+  ExplodedNodeImpl* Pred;
   ExplodedNodeImpl* LastNode;  
   bool HasGeneratedNode;
   bool Populated;
@@ -136,7 +137,9 @@ public:
   
   ~GRStmtNodeBuilderImpl();
   
-  inline ExplodedNodeImpl* getLastNode() {
+  ExplodedNodeImpl* getBasePredecessor() const { return Pred; }
+  
+  ExplodedNodeImpl* getLastNode() const {
     return LastNode ? (LastNode->isSink() ? NULL : LastNode) : NULL;
   }
   
@@ -160,9 +163,12 @@ class GRStmtNodeBuilder  {
   typedef ExplodedNode<StateTy>   NodeTy;
   
   GRStmtNodeBuilderImpl& NB;
+  StateTy* CleanedState;
   
 public:
-  GRStmtNodeBuilder(GRStmtNodeBuilderImpl& nb) : NB(nb), BuildSinks(false) {}
+  GRStmtNodeBuilder(GRStmtNodeBuilderImpl& nb) : NB(nb), BuildSinks(false) {
+    CleanedState = getLastNode()->getState();
+  }
     
   NodeTy* getLastNode() const {
     return static_cast<NodeTy*>(NB.getLastNode());
@@ -176,12 +182,24 @@ public:
     return static_cast<NodeTy*>(NB.generateNodeImpl(S, St));    
   }
   
+  StateTy* GetState(NodeTy* Pred) const {
+    if ((ExplodedNodeImpl*) Pred == NB.getBasePredecessor())
+      return CleanedState;
+    else
+      return Pred->getState();
+  }
+  
+  void SetCleanedState(StateTy* St) {
+    CleanedState = St;
+  }
+  
   NodeTy* Nodify(ExplodedNodeSet<StateTy>& Dst, Stmt* S,
                  NodeTy* Pred, StateTy* St) {    
     
+    StateTy* PredState = GetState(Pred);
     
     // If the state hasn't changed, don't generate a new node.
-    if (!BuildSinks && St == Pred->getState()) {
+    if (!BuildSinks && St == PredState) {
       Dst.Add(Pred);
       return NULL;
     }