region store: make Retrieve() can retrieve embedded array correctly. Also
simplify the retrieve logic. llvm-svn: 70651
This commit is contained in:
parent
b7126db9b0
commit
3e3e69bbe7
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue