From 3e3e69bbe72308336ac955b1e21cb9d121496ac3 Mon Sep 17 00:00:00 2001 From: Zhongxing Xu Date: Sun, 3 May 2009 00:27:40 +0000 Subject: [PATCH] region store: make Retrieve() can retrieve embedded array correctly. Also simplify the retrieve logic. llvm-svn: 70651 --- clang/lib/Analysis/RegionStore.cpp | 49 ++++++++++++++++++------------ clang/test/Analysis/array-struct.c | 11 +++++++ 2 files changed, 41 insertions(+), 19 deletions(-) diff --git a/clang/lib/Analysis/RegionStore.cpp b/clang/lib/Analysis/RegionStore.cpp index aeb8a2ac8f86..8f573c39884d 100644 --- a/clang/lib/Analysis/RegionStore.cpp +++ b/clang/lib/Analysis/RegionStore.cpp @@ -270,6 +270,8 @@ private: /// y's value is retrieved by this method. SVal RetrieveStruct(const GRState* St, const TypedRegion* R); + SVal RetrieveArray(const GRState* St, const TypedRegion* R); + const GRState* BindStruct(const GRState* St, const TypedRegion* R, SVal V); /// KillStruct - Set the entire struct to unknown. @@ -652,8 +654,13 @@ SVal RegionStoreManager::Retrieve(const GRState* St, Loc L, QualType T) { // Such funny addressing will occur due to layering of regions. QualType RTy = R->getRValueType(getContext()); + if (RTy->isStructureType()) return RetrieveStruct(St, R); + + if (RTy->isArrayType()) + return RetrieveArray(St, R); + // FIXME: handle Vector types. if (RTy->isVectorType()) return UnknownVal(); @@ -732,10 +739,6 @@ SVal RegionStoreManager::Retrieve(const GRState* St, Loc L, QualType T) { } SVal RegionStoreManager::RetrieveStruct(const GRState* St,const TypedRegion* R){ - - Store store = St->getStore(); - GRStateRef state(St, StateMgr); - // FIXME: Verify we want getRValueType instead of getLValueType. QualType T = R->getRValueType(getContext()); assert(T->isStructureType()); @@ -753,27 +756,35 @@ SVal RegionStoreManager::RetrieveStruct(const GRState* St,const TypedRegion* R){ FieldEnd = Fields.rend(); Field != FieldEnd; ++Field) { FieldRegion* FR = MRMgr.getFieldRegion(*Field, R); - RegionBindingsTy B = GetRegionBindings(store); - RegionBindingsTy::data_type* data = B.lookup(FR); - - SVal FieldValue; - if (data) - FieldValue = *data; - else if (state.contains(FR)) - FieldValue = UnknownVal(); - else { - if (MRMgr.onStack(FR) || MRMgr.onHeap(FR)) - FieldValue = UndefinedVal(); - else - FieldValue = ValMgr.getRValueSymbolVal(FR); - } - + QualType FTy = (*Field)->getType(); + SVal FieldValue = Retrieve(St, loc::MemRegionVal(FR), FTy); StructVal = getBasicVals().consVals(FieldValue, StructVal); } return NonLoc::MakeCompoundVal(T, StructVal, getBasicVals()); } +SVal RegionStoreManager::RetrieveArray(const GRState* St, const TypedRegion* R){ + QualType T = R->getRValueType(getContext()); + ConstantArrayType* CAT = cast(T.getTypePtr()); + + llvm::ImmutableList ArrayVal = getBasicVals().getEmptySValList(); + + llvm::APSInt Size(CAT->getSize(), false); + llvm::APSInt i = getBasicVals().getValue(0, Size.getBitWidth(), + Size.isUnsigned()); + + for (; i < Size; ++i) { + SVal Idx = NonLoc::MakeVal(getBasicVals(), i); + ElementRegion* ER = MRMgr.getElementRegion(Idx, R); + QualType ETy = ER->getRValueType(getContext()); + SVal ElementVal = Retrieve(St, loc::MemRegionVal(ER), ETy); + ArrayVal = getBasicVals().consVals(ElementVal, ArrayVal); + } + + return NonLoc::MakeCompoundVal(T, ArrayVal, getBasicVals()); +} + const GRState* RegionStoreManager::Bind(const GRState* St, Loc L, SVal V) { // If we get here, the location should be a region. const MemRegion* R = cast(L).getRegion(); diff --git a/clang/test/Analysis/array-struct.c b/clang/test/Analysis/array-struct.c index 7e5e6243c6a8..0ce6afcc0c0a 100644 --- a/clang/test/Analysis/array-struct.c +++ b/clang/test/Analysis/array-struct.c @@ -119,3 +119,14 @@ void f13(double timeout) { if (a.e.d == 10) a.e.d = 4; } + +struct s3 { + int a[2]; +}; + +static struct s3 opt; + +// Test if the embedded array is retrieved correctly. +void f14() { + struct s3 my_opt = opt; +}