From: Zhongxing Xu Date: Fri, 7 Nov 2008 10:38:33 +0000 (+0000) Subject: Finish the implementation of VisitCompoundLiteralExpr. As VisitInitListExpr is X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f22679e3e5d5f5754931952e58112b4c863a4137;p=clang Finish the implementation of VisitCompoundLiteralExpr. As VisitInitListExpr is available, things get much simplified. One addition is that CompoundLiteralExpr can appear both in rvalue and lvalue context. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@58837 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h index af5a10346e..86853627ee 100644 --- a/include/clang/Analysis/PathSensitive/GRExprEngine.h +++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h @@ -505,7 +505,7 @@ protected: /// VisitCompoundLiteralExpr - Transfer function logic for compound literals. void VisitCompoundLiteralExpr(CompoundLiteralExpr* CL, NodeTy* Pred, - NodeSet& Dst); + NodeSet& Dst, bool asLValue); /// VisitDeclRefExpr - Transfer function logic for DeclRefExprs. void VisitDeclRefExpr(DeclRefExpr* DR, NodeTy* Pred, NodeSet& Dst, diff --git a/include/clang/Analysis/PathSensitive/GRState.h b/include/clang/Analysis/PathSensitive/GRState.h index 1563b412da..9b99251381 100644 --- a/include/clang/Analysis/PathSensitive/GRState.h +++ b/include/clang/Analysis/PathSensitive/GRState.h @@ -336,8 +336,7 @@ public: /// for the compound literal and 'BegInit' and 'EndInit' represent an /// array of initializer values. const GRState* BindCompoundLiteral(const GRState* state, - const CompoundLiteralRegion* R, - const SVal* BegInit, const SVal* EndInit); + const CompoundLiteralExpr* CL, SVal V); const GRState* RemoveDeadBindings(const GRState* St, Stmt* Loc, const LiveVariables& Liveness, @@ -369,7 +368,11 @@ public: SVal GetLValue(const GRState* St, const StringLiteral* E) { return StoreMgr->getLValueString(St, E); } - + + SVal GetLValue(const GRState* St, const CompoundLiteralExpr* CL) { + return StoreMgr->getLValueCompoundLiteral(St, CL); + } + // Get the lvalue for an ivar reference. SVal GetLValue(const GRState* St, const ObjCIvarDecl* D, SVal Base) { return StoreMgr->getLValueIvar(St, D, Base); diff --git a/include/clang/Analysis/PathSensitive/Store.h b/include/clang/Analysis/PathSensitive/Store.h index 4c08fe6dd3..a36d320a19 100644 --- a/include/clang/Analysis/PathSensitive/Store.h +++ b/include/clang/Analysis/PathSensitive/Store.h @@ -52,9 +52,8 @@ public: /// 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. - virtual Store BindCompoundLiteral(Store store, const CompoundLiteralRegion* R, - const SVal* BegInit, - const SVal* EndInit) = 0; + virtual Store BindCompoundLiteral(Store store, const CompoundLiteralExpr* CL, + SVal V) = 0; virtual Store getInitialStore() = 0; virtual MemRegionManager& getRegionManager() = 0; @@ -62,6 +61,9 @@ public: virtual SVal getLValueVar(const GRState* St, const VarDecl* VD) = 0; virtual SVal getLValueString(const GRState* St, const StringLiteral* S) = 0; + + virtual SVal getLValueCompoundLiteral(const GRState* St, + const CompoundLiteralExpr* CL) = 0; virtual SVal getLValueIvar(const GRState* St, const ObjCIvarDecl* D, SVal Base) = 0; diff --git a/lib/Analysis/BasicStore.cpp b/lib/Analysis/BasicStore.cpp index de5ff30db9..be9f4fdd12 100644 --- a/lib/Analysis/BasicStore.cpp +++ b/lib/Analysis/BasicStore.cpp @@ -46,13 +46,15 @@ public: return loc::MemRegionVal(MRMgr.getVarRegion(VD)); } - Store BindCompoundLiteral(Store store, const CompoundLiteralRegion* R, - const SVal* BegInit, const SVal* EndInit) { + Store BindCompoundLiteral(Store store, const CompoundLiteralExpr* CL, + SVal V) { return store; } SVal getLValueVar(const GRState* St, const VarDecl* VD); SVal getLValueString(const GRState* St, const StringLiteral* S); + SVal getLValueCompoundLiteral(const GRState* St, + const CompoundLiteralExpr* CL); SVal getLValueIvar(const GRState* St, const ObjCIvarDecl* D, SVal Base); SVal getLValueField(const GRState* St, SVal Base, const FieldDecl* D); SVal getLValueElement(const GRState* St, SVal Base, SVal Offset); @@ -99,7 +101,12 @@ SVal BasicStoreManager::getLValueString(const GRState* St, const StringLiteral* S) { return loc::MemRegionVal(MRMgr.getStringRegion(S)); } - + +SVal BasicStoreManager::getLValueCompoundLiteral(const GRState* St, + const CompoundLiteralExpr* CL){ + return loc::MemRegionVal(MRMgr.getCompoundLiteralRegion(CL)); +} + SVal BasicStoreManager::getLValueIvar(const GRState* St, const ObjCIvarDecl* D, SVal Base) { return UnknownVal(); diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index 6162592437..e2c23b4942 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -329,6 +329,10 @@ void GRExprEngine::Visit(Stmt* S, NodeTy* Pred, NodeSet& Dst) { case Stmt::CompoundAssignOperatorClass: VisitBinaryOperator(cast(S), Pred, Dst); break; + + case Stmt::CompoundLiteralExprClass: + VisitCompoundLiteralExpr(cast(S), Pred, Dst, false); + break; case Stmt::ConditionalOperatorClass: { // '?' operator ConditionalOperator* C = cast(S); @@ -435,7 +439,7 @@ void GRExprEngine::VisitLValue(Expr* Ex, NodeTy* Pred, NodeSet& Dst) { return; case Stmt::CompoundLiteralExprClass: - VisitCompoundLiteralExpr(cast(Ex), Pred, Dst); + VisitCompoundLiteralExpr(cast(Ex), Pred, Dst, true); return; case Stmt::ObjCPropertyRefExprClass: @@ -1575,31 +1579,21 @@ 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? + NodeTy* Pred, NodeSet& Dst, + bool asLValue) { InitListExpr* ILE = cast(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 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(*J))); - - const CompoundLiteralRegion* R = - StateMgr.getRegionManager().getCompoundLiteralRegion(CL); - - assert (!IVals.empty() && "Initializer cannot be empty."); + const GRState* St = GetState(*I); + SVal ILV = GetSVal(St, ILE); + St = StateMgr.BindCompoundLiteral(St, CL, ILV); - St = StateMgr.BindCompoundLiteral(St, R, &IVals[0], &IVals[0]+IVals.size()); - MakeNode(Dst, CL, *I, BindExpr(St, CL, loc::MemRegionVal(R))); + if (asLValue) + MakeNode(Dst, CL, *I, BindExpr(St, CL, StateMgr.GetLValue(St, CL))); + else + MakeNode(Dst, CL, *I, BindExpr(St, CL, ILV)); } } diff --git a/lib/Analysis/GRState.cpp b/lib/Analysis/GRState.cpp index a5bc429586..57f9c6b279 100644 --- a/lib/Analysis/GRState.cpp +++ b/lib/Analysis/GRState.cpp @@ -96,11 +96,10 @@ const GRState* GRStateManager::BindDecl(const GRState* St, const VarDecl* VD, /// array of initializer values. const GRState* GRStateManager::BindCompoundLiteral(const GRState* state, - const CompoundLiteralRegion* R, - const SVal* BegInit, const SVal* EndInit) { + const CompoundLiteralExpr* CL, SVal ILV) { Store oldStore = state->getStore(); - Store newStore = StoreMgr->BindCompoundLiteral(oldStore, R, BegInit, EndInit); + Store newStore = StoreMgr->BindCompoundLiteral(oldStore, CL, ILV); if (newStore == oldStore) return state; diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp index 2000d80ca5..20a8ae0d05 100644 --- a/lib/Analysis/RegionStore.cpp +++ b/lib/Analysis/RegionStore.cpp @@ -46,17 +46,12 @@ public: 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; - } + Store BindCompoundLiteral(Store store, const CompoundLiteralExpr* CL, SVal V); SVal getLValueString(const GRState* St, const StringLiteral* S); + SVal getLValueCompoundLiteral(const GRState* St, const CompoundLiteralExpr*); + SVal getLValueVar(const GRState* St, const VarDecl* VD); SVal getLValueIvar(const GRState* St, const ObjCIvarDecl* D, SVal Base); @@ -137,7 +132,12 @@ SVal RegionStoreManager::getLValueString(const GRState* St, SVal RegionStoreManager::getLValueVar(const GRState* St, const VarDecl* VD) { return loc::MemRegionVal(MRMgr.getVarRegion(VD)); } - + +SVal RegionStoreManager::getLValueCompoundLiteral(const GRState* St, + const CompoundLiteralExpr* CL) { + return loc::MemRegionVal(MRMgr.getCompoundLiteralRegion(CL)); +} + SVal RegionStoreManager::getLValueIvar(const GRState* St, const ObjCIvarDecl* D, SVal Base) { return UnknownVal(); @@ -424,6 +424,14 @@ Store RegionStoreManager::BindDecl(Store store, const VarDecl* VD, Expr* Ex, return store; } +Store RegionStoreManager::BindCompoundLiteral(Store store, + const CompoundLiteralExpr* CL, + SVal V) { + CompoundLiteralRegion* R = MRMgr.getCompoundLiteralRegion(CL); + store = Bind(store, loc::MemRegionVal(R), V); + return store; +} + void RegionStoreManager::print(Store store, std::ostream& Out, const char* nl, const char *sep) { llvm::raw_os_ostream OS(Out);