diff options
author | Ted Kremenek <kremenek@apple.com> | 2008-03-10 04:45:00 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2008-03-10 04:45:00 +0000 |
commit | 3bbad550be7edc628be31b51d2a51b6d7d46eafb (patch) | |
tree | 88782bbdd64971b2436ff3b1186a9b4574749ce8 | |
parent | 0d093d3005dd583675a45a85bd688063572cc8af (diff) |
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
-rw-r--r-- | Analysis/GRCoreEngine.cpp | 2 | ||||
-rw-r--r-- | Analysis/GRExprEngine.cpp | 2 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/GRCoreEngine.h | 24 |
3 files changed, 24 insertions, 4 deletions
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<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; } |