From 1c64daba5bae3790429fc455a530e466a6a3a8cf Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Wed, 27 Feb 2008 06:47:26 +0000 Subject: [PATCH] When analyzing a function, eagerly create symbolic values for all globals/parameters at the beginning of the analysis. llvm-svn: 47664 --- clang/Analysis/GRExprEngine.cpp | 55 +++++++++---------- clang/Analysis/ValueState.cpp | 6 +- .../Analysis/PathSensitive/GRExprEngine.h | 11 +--- .../clang/Analysis/PathSensitive/ValueState.h | 1 + 4 files changed, 32 insertions(+), 41 deletions(-) diff --git a/clang/Analysis/GRExprEngine.cpp b/clang/Analysis/GRExprEngine.cpp index d2200bfa0fef..758e038865fd 100644 --- a/clang/Analysis/GRExprEngine.cpp +++ b/clang/Analysis/GRExprEngine.cpp @@ -26,6 +26,30 @@ using llvm::dyn_cast; using llvm::cast; using llvm::APSInt; +GRExprEngine::StateTy GRExprEngine::getInitialState() { + + // The LiveVariables information already has a compilation of all VarDecls + // used in the function. Iterate through this set, and "symbolicate" + // any VarDecl whose value originally comes from outside the function. + + typedef LiveVariables::AnalysisDataTy LVDataTy; + LVDataTy& D = Liveness.getAnalysisData(); + + ValueStateImpl StateImpl = *StateMgr.getInitialState().getImpl(); + + for (LVDataTy::decl_iterator I=D.begin_decl(), E=D.end_decl(); I != E; ++I) { + + VarDecl* VD = cast(const_cast(I->first)); + + if (VD->hasGlobalStorage() || isa(VD)) { + RVal X = RVal::GetSymbolValue(SymMgr, VD); + StateMgr.BindVar(StateImpl, VD, X); + } + } + + return StateMgr.getPersistentState(StateImpl); +} + GRExprEngine::StateTy GRExprEngine::SetRVal(StateTy St, Expr* Ex, const RVal& V) { @@ -455,22 +479,6 @@ void GRExprEngine::Nodify(NodeSet& Dst, Stmt* S, NodeTy* Pred, void GRExprEngine::VisitDeclRefExpr(DeclRefExpr* D, NodeTy* Pred, NodeSet& Dst){ - if (VarDecl* VD = dyn_cast(D->getDecl())) - if (VD->hasGlobalStorage() || isa(VD)) { - - StateTy StOld = Pred->getState(); - StateTy St = Symbolicate(StOld, VD); - - if (!(St == StOld)) { - if (D != CurrentStmt) - Nodify(Dst, D, Pred, St); - else - Nodify(Dst, D, Pred, SetRVal(St, D, GetRVal(St, D))); - - return; - } - } - if (D != CurrentStmt) { Dst.Add(Pred); // No-op. Simply propagate the current state unchanged. return; @@ -884,20 +892,7 @@ void GRExprEngine::VisitLVal(Expr* Ex, NodeTy* Pred, NodeSet& Dst) { Ex = Ex->IgnoreParens(); - if (DeclRefExpr* DR = dyn_cast(Ex)) { - - if (VarDecl* VD = dyn_cast(DR->getDecl())) - if (VD->hasGlobalStorage() || isa(VD)) { - - StateTy StOld = Pred->getState(); - StateTy St = Symbolicate(StOld, VD); - - if (!(St == StOld)) { - Nodify(Dst, Ex, Pred, St); - return; - } - } - + if (isa(Ex)) { Dst.Add(Pred); return; } diff --git a/clang/Analysis/ValueState.cpp b/clang/Analysis/ValueState.cpp index cdd616fb147a..b90e265af246 100644 --- a/clang/Analysis/ValueState.cpp +++ b/clang/Analysis/ValueState.cpp @@ -437,10 +437,14 @@ ValueState ValueStateManager::SetRVal(ValueState St, LVal LV, RVal V) { } } +void ValueStateManager::BindVar(ValueStateImpl& StImpl, VarDecl* D, RVal V) { + StImpl.VarBindings = VBFactory.Add(StImpl.VarBindings, D, V); +} + ValueState ValueStateManager::BindVar(ValueState St, VarDecl* D, RVal V) { // Create a new state with the old binding removed. - ValueStateImpl NewSt = *St; + ValueStateImpl NewSt = *St; NewSt.VarBindings = VBFactory.Add(NewSt.VarBindings, D, V); // Get the persistent copy. diff --git a/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h b/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h index 16fd97710500..13abf53cb39f 100644 --- a/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h +++ b/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h @@ -150,7 +150,7 @@ public: /// getInitialState - Return the initial state used for the root vertex /// in the ExplodedGraph. - StateTy getInitialState() { return StateMgr.getInitialState(); } + StateTy getInitialState(); bool isUninitControlFlow(const NodeTy* N) const { return N->isSink() && UninitBranches.count(const_cast(N)) != 0; @@ -252,15 +252,6 @@ protected: return StateMgr.GetLVal(St, Ex); } - StateTy Symbolicate(StateTy St, VarDecl* VD) { - lval::DeclVal X(VD); - - if (GetRVal(St, X).isUnknown()) { - return SetRVal(St, lval::DeclVal(VD), RVal::GetSymbolValue(SymMgr, VD)); - } - else return St; - } - inline NonLVal MakeConstantVal(uint64_t X, Expr* Ex) { return NonLVal::MakeVal(ValMgr, X, Ex->getType(), Ex->getLocStart()); } diff --git a/clang/include/clang/Analysis/PathSensitive/ValueState.h b/clang/include/clang/Analysis/PathSensitive/ValueState.h index 5458ab86e59c..c3e913ab703f 100644 --- a/clang/include/clang/Analysis/PathSensitive/ValueState.h +++ b/clang/include/clang/Analysis/PathSensitive/ValueState.h @@ -266,6 +266,7 @@ public: RVal GetBlkExprRVal(ValueState St, Expr* Ex); + void BindVar(ValueStateImpl& StImpl, VarDecl* D, RVal V); ValueState getPersistentState(const ValueStateImpl& Impl); ValueState AddEQ(ValueState St, SymbolID sym, const llvm::APSInt& V);