forked from OSchip/llvm-project
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:
parent
e7e659431c
commit
cea6578078
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue