diff options
Diffstat (limited to 'lib')
-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); |