From: Ted Kremenek Date: Mon, 10 Mar 2008 04:45:00 +0000 (+0000) Subject: More edge-case handling with using liveness information to prune dead state values. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3bbad550be7edc628be31b51d2a51b6d7d46eafb;p=clang More edge-case handling with using liveness information to prune dead state values. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@48127 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Analysis/GRCoreEngine.cpp b/Analysis/GRCoreEngine.cpp index cff33373cf..53831ed06d 100644 --- a/Analysis/GRCoreEngine.cpp +++ b/Analysis/GRCoreEngine.cpp @@ -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); } diff --git a/Analysis/GRExprEngine.cpp b/Analysis/GRExprEngine.cpp index aafc735c9a..15fe88ec1c 100644 --- a/Analysis/GRExprEngine.cpp +++ b/Analysis/GRExprEngine.cpp @@ -403,6 +403,8 @@ void GRExprEngine::ProcessStmt(Stmt* S, StmtNodeBuilder& builder) { CleanedState = StateMgr.RemoveDeadBindings(StmtEntryNode->getState(), CurrentStmt, Liveness); + + Builder->SetCleanedState(CleanedState); // Visit the statement. diff --git a/include/clang/Analysis/PathSensitive/GRCoreEngine.h b/include/clang/Analysis/PathSensitive/GRCoreEngine.h index 37dddea281..9a8be4e0fd 100644 --- a/include/clang/Analysis/PathSensitive/GRCoreEngine.h +++ b/include/clang/Analysis/PathSensitive/GRCoreEngine.h @@ -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 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(NB.getLastNode()); @@ -176,12 +182,24 @@ public: return static_cast(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& 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; }