When casting region, if we do not create an element region, record the cast-to

type. 

When retrieving the region value, if we are going to create a symbol value, use
the cast-to type if possible.

llvm-svn: 73690
This commit is contained in:
Zhongxing Xu 2009-06-18 06:29:10 +00:00
parent e7e659431c
commit cea6578078
4 changed files with 38 additions and 9 deletions

View File

@ -81,7 +81,7 @@ public:
SVal makeZeroArrayIndex(); SVal makeZeroArrayIndex();
/// GetRegionValueSymbolVal - make a unique symbol for value of R. /// GetRegionValueSymbolVal - make a unique symbol for value of R.
SVal getRegionValueSymbolVal(const MemRegion* R); SVal getRegionValueSymbolVal(const MemRegion* R, QualType T = QualType());
SVal getConjuredSymbolVal(const Expr *E, unsigned Count); SVal getConjuredSymbolVal(const Expr *E, unsigned Count);
SVal getConjuredSymbolVal(const Expr* E, QualType T, unsigned Count); SVal getConjuredSymbolVal(const Expr* E, QualType T, unsigned Count);

View File

@ -584,6 +584,7 @@ SVal RegionStoreManager::getSizeInElements(const GRState *state,
QualType VarTy = VR->getValueType(getContext()); QualType VarTy = VR->getValueType(getContext());
uint64_t EleSize = getContext().getTypeSize(EleTy); uint64_t EleSize = getContext().getTypeSize(EleTy);
uint64_t VarSize = getContext().getTypeSize(VarTy); uint64_t VarSize = getContext().getTypeSize(VarTy);
assert(VarSize != 0);
return NonLoc::MakeIntVal(getBasicVals(), VarSize / EleSize, false); return NonLoc::MakeIntVal(getBasicVals(), VarSize / EleSize, false);
} }
@ -710,15 +711,18 @@ RegionStoreManager::CastRegion(const GRState *state, const MemRegion* R,
uint64_t ObjTySize = getContext().getTypeSize(ObjTy); uint64_t ObjTySize = getContext().getTypeSize(ObjTy);
if ((PointeeTySize > 0 && PointeeTySize < ObjTySize) || if ((PointeeTySize > 0 && PointeeTySize < ObjTySize) ||
(ObjTy->isAggregateType() && PointeeTy->isScalarType())) { (ObjTy->isAggregateType() && PointeeTy->isScalarType()) ||
ObjTySize == 0 /* R has 'void*' type. */) {
// Record the cast type of the region. // Record the cast type of the region.
state = setCastType(state, R, ToTy); state = setCastType(state, R, ToTy);
SVal Idx = ValMgr.makeZeroArrayIndex(); SVal Idx = ValMgr.makeZeroArrayIndex();
ElementRegion* ER = MRMgr.getElementRegion(PointeeTy, Idx,R,getContext()); ElementRegion* ER = MRMgr.getElementRegion(PointeeTy, Idx,R,getContext());
return CastResult(state, ER); return CastResult(state, ER);
} else } else {
state = setCastType(state, R, ToTy);
return CastResult(state, R); return CastResult(state, R);
}
} }
if (isa<ObjCObjectRegion>(R)) { if (isa<ObjCObjectRegion>(R)) {
@ -930,14 +934,22 @@ SVal RegionStoreManager::Retrieve(const GRState *state, Loc L, QualType T) {
return UndefinedVal(); return UndefinedVal();
} }
// If the region is already cast to another type, use that type to create the
// symbol value.
if (const QualType *p = state->get<RegionCasts>(R)) {
QualType T = *p;
RTy = T->getAsPointerType()->getPointeeType();
}
// All other integer values are symbolic. // All other integer values are symbolic.
if (Loc::IsLocType(RTy) || RTy->isIntegerType()) if (Loc::IsLocType(RTy) || RTy->isIntegerType())
return ValMgr.getRegionValueSymbolVal(R); return ValMgr.getRegionValueSymbolVal(R, RTy);
else else
return UnknownVal(); return UnknownVal();
} }
SVal RegionStoreManager::RetrieveStruct(const GRState *state, const TypedRegion* R){ SVal RegionStoreManager::RetrieveStruct(const GRState *state,
const TypedRegion* R){
QualType T = R->getValueType(getContext()); QualType T = R->getValueType(getContext());
assert(T->isStructureType()); assert(T->isStructureType());
@ -1220,8 +1232,8 @@ const GRState *RegionStoreManager::RemoveRegionView(const GRState *state,
return state->set<RegionViewMap>(Base, RVFactory.Remove(*d, View)); return state->set<RegionViewMap>(Base, RVFactory.Remove(*d, View));
} }
const GRState *RegionStoreManager::setCastType(const GRState *state, const MemRegion* R, const GRState *RegionStoreManager::setCastType(const GRState *state,
QualType T) { const MemRegion* R, QualType T) {
return state->set<RegionCasts>(R, T); return state->set<RegionCasts>(R, T);
} }

View File

@ -322,11 +322,12 @@ NonLoc NonLoc::MakeCompoundVal(QualType T, llvm::ImmutableList<SVal> Vals,
return nonloc::CompoundVal(BasicVals.getCompoundValData(T, Vals)); return nonloc::CompoundVal(BasicVals.getCompoundValData(T, Vals));
} }
SVal ValueManager::getRegionValueSymbolVal(const MemRegion* R) { SVal ValueManager::getRegionValueSymbolVal(const MemRegion* R, QualType T) {
SymbolRef sym = SymMgr.getRegionValueSymbol(R); SymbolRef sym = SymMgr.getRegionValueSymbol(R);
if (const TypedRegion* TR = dyn_cast<TypedRegion>(R)) { if (const TypedRegion* TR = dyn_cast<TypedRegion>(R)) {
QualType T = TR->getValueType(SymMgr.getContext()); if (!T.getTypePtr())
T = TR->getValueType(SymMgr.getContext());
// If T is of function pointer type, create a CodeTextRegion wrapping a // If T is of function pointer type, create a CodeTextRegion wrapping a
// symbol. // symbol.

View File

@ -14,3 +14,19 @@ void f(int sock) {
; ;
} }
} }
struct s {
struct s *value;
};
// ElementRegion and cast-to pointee type may be of the same size:
// 'struct s **' and 'int'.
int f1(struct s **pval) {
int *tbool = ((void*)0);
struct s *t = *pval;
pval = &(t->value);
tbool = (int *)pval;
char c = (unsigned char) *tbool;
}