region store: make Retrieve() can retrieve embedded array correctly. Also

simplify the retrieve logic.

llvm-svn: 70651
This commit is contained in:
Zhongxing Xu 2009-05-03 00:27:40 +00:00
parent b7126db9b0
commit 3e3e69bbe7
2 changed files with 41 additions and 19 deletions

View File

@ -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();

View File

@ -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;
}