diff options
author | Zhongxing Xu <xuzhongxing@gmail.com> | 2009-05-03 00:27:40 +0000 |
---|---|---|
committer | Zhongxing Xu <xuzhongxing@gmail.com> | 2009-05-03 00:27:40 +0000 |
commit | 3e001f393d112a50e13c9a8f9a4c0d97f3f51cf4 (patch) | |
tree | 34cf9fc0608ba3d039a8c20862f1e2590c08fb39 /lib/Analysis/RegionStore.cpp | |
parent | 45d604e039e94532f5a78d15df94e71b4aa2ba49 (diff) |
region store: make Retrieve() can retrieve embedded array correctly. Also
simplify the retrieve logic.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70651 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/RegionStore.cpp')
-rw-r--r-- | lib/Analysis/RegionStore.cpp | 49 |
1 files changed, 30 insertions, 19 deletions
diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp index aeb8a2ac8f..8f573c3988 100644 --- a/lib/Analysis/RegionStore.cpp +++ b/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<RegionKills>(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<ConstantArrayType>(T.getTypePtr()); + + llvm::ImmutableList<SVal> 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<loc::MemRegionVal>(L).getRegion(); |