diff options
author | Ted Kremenek <kremenek@apple.com> | 2008-10-27 21:54:31 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2008-10-27 21:54:31 +0000 |
commit | 4f09027385466f1f4c382c80ca77157e2aef97d9 (patch) | |
tree | d27a15491869214b0619dda1cbcbf277e2e13135 /lib/Analysis | |
parent | 664a2187c7ac47e95ab2c72d4ba7e805e966b430 (diff) |
Added preliminary support for CompoundLiterals in the static analyzer:
- GRExprEngine::VisitCompoundLiteral...
(1) visits the initializer list (generating ExplodedNodes)
(2) creates a CompoundMemRegion for the literal
(3) creates a new state with the bound literal values using
GRStateManager::BindCompoundLiteral
- GRStateManager::BindCompoundLiteral simply calls
StoreManager::BindCompoundLiteral to get a new store and returns a persistent
GRState with that store.
- BasicStore::BindCompoundLiteral simply returns the same store, as it
doesn't handle field sensitivity
- RegionStore::BindCompoundLiteral currently fires an assert (pending discussion
of how to best implement mappings for CompoundLiteralRegion).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@58277 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis')
-rw-r--r-- | lib/Analysis/BasicStore.cpp | 5 | ||||
-rw-r--r-- | lib/Analysis/GRExprEngine.cpp | 33 | ||||
-rw-r--r-- | lib/Analysis/GRState.cpp | 20 | ||||
-rw-r--r-- | lib/Analysis/RegionStore.cpp | 9 |
4 files changed, 67 insertions, 0 deletions
diff --git a/lib/Analysis/BasicStore.cpp b/lib/Analysis/BasicStore.cpp index 8895954502..05c8523d2d 100644 --- a/lib/Analysis/BasicStore.cpp +++ b/lib/Analysis/BasicStore.cpp @@ -46,6 +46,11 @@ public: return loc::MemRegionVal(MRMgr.getVarRegion(VD)); } + Store BindCompoundLiteral(Store store, const CompoundLiteralRegion* R, + const SVal* BegInit, const SVal* EndInit) { + return store; + } + SVal getLValueVar(const GRState* St, const VarDecl* VD); SVal getLValueString(const GRState* St, const StringLiteral* S); SVal getLValueIvar(const GRState* St, const ObjCIvarDecl* D, SVal Base); diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index 282a08c21a..67dd79a193 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -430,6 +430,10 @@ void GRExprEngine::VisitLValue(Expr* Ex, NodeTy* Pred, NodeSet& Dst) { VisitMemberExpr(cast<MemberExpr>(Ex), Pred, Dst, true); return; + case Stmt::CompoundLiteralExprClass: + VisitCompoundLiteralExpr(cast<CompoundLiteralExpr>(Ex), Pred, Dst); + return; + case Stmt::ObjCPropertyRefExprClass: // FIXME: Property assignments are lvalues, but not really "locations". // e.g.: self.x = something; @@ -1530,6 +1534,35 @@ void GRExprEngine::VisitCast(Expr* CastE, Expr* Ex, NodeTy* Pred, NodeSet& Dst){ } } +void GRExprEngine::VisitCompoundLiteralExpr(CompoundLiteralExpr* CL, + NodeTy* Pred, NodeSet& Dst) { + + // FIXME: Can getInitializer() be NULL? + InitListExpr* ILE = cast<InitListExpr>(CL->getInitializer()->IgnoreParens()); + NodeSet Tmp; + Visit(ILE, Pred, Tmp); + + for (NodeSet::iterator I = Tmp.begin(), EI = Tmp.end(); I!=EI; ++I) { + // Retrieve the initializer values from the environment and store them + // into a vector that will then be handed off to the Store. + const GRState* St = GetState(*I); + llvm::SmallVector<SVal, 10> IVals; + IVals.reserve(ILE->getNumInits()); + + for (Stmt::child_iterator J=ILE->child_begin(), EJ=ILE->child_end(); + J!=EJ; ++J) + IVals.push_back(GetSVal(St, cast<Expr>(*J))); + + const CompoundLiteralRegion* R = + StateMgr.getRegionManager().getCompoundLiteralRegion(CL); + + assert (!IVals.empty() && "Initializer cannot be empty."); + + St = StateMgr.BindCompoundLiteral(St, R, &IVals[0], &IVals[0]+IVals.size()); + MakeNode(Dst, CL, *I, SetSVal(St, CL, loc::MemRegionVal(R))); + } +} + void GRExprEngine::VisitDeclStmt(DeclStmt* DS, NodeTy* Pred, NodeSet& Dst) { // The CFG has one DeclStmt per Decl. diff --git a/lib/Analysis/GRState.cpp b/lib/Analysis/GRState.cpp index 828be2229f..03b724779e 100644 --- a/lib/Analysis/GRState.cpp +++ b/lib/Analysis/GRState.cpp @@ -92,6 +92,26 @@ const GRState* GRStateManager::AddDecl(const GRState* St, const VarDecl* VD, return getPersistentState(NewSt); } +/// BindCompoundLiteral - Return the store that has the bindings currently +/// in 'store' plus the bindings for the CompoundLiteral. 'R' is the region +/// for the compound literal and 'BegInit' and 'EndInit' represent an +/// array of initializer values. +const GRState* +GRStateManager::BindCompoundLiteral(const GRState* state, + const CompoundLiteralRegion* R, + const SVal* BegInit, const SVal* EndInit) { + + Store oldStore = state->getStore(); + Store newStore = StoreMgr->BindCompoundLiteral(oldStore, R, BegInit, EndInit); + + if (newStore == oldStore) + return state; + + GRState newState = *state; + newState.St = newStore; + return getPersistentState(newState); +} + const GRState* GRStateManager::Unbind(const GRState* St, Loc LV) { Store OldStore = St->getStore(); Store NewStore = StoreMgr->Remove(OldStore, LV); diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp index 6a65919b1e..1c73ceae20 100644 --- a/lib/Analysis/RegionStore.cpp +++ b/lib/Analysis/RegionStore.cpp @@ -45,6 +45,15 @@ public: SVal GetRegionSVal(Store St, const MemRegion* R) { return Retrieve(St, loc::MemRegionVal(R)); } + + Store BindCompoundLiteral(Store store, const CompoundLiteralRegion* R, + const SVal* BegInit, const SVal* EndInit) { + + // FIXME: Let's discuss how we want to do the mapping in RegionStore + // from CompoundLiteralRegion to values. + assert (false && "Not yet implemented."); + return store; + } SVal getLValueString(const GRState* St, const StringLiteral* S); |