RegionStore:
-refactor logic for retrieving bindings from VarDecls into RegionStoreManager::RetrieveVar() - improve RegionStoreManager::CastRetrievedVal() and SimpleSValuate::EvalCastNL to better handle casts of values of the same canonical type as well as casts of LocAsInteger values. llvm-svn: 76516
This commit is contained in:
parent
05ac8276cf
commit
fe12f88924
|
|
@ -287,6 +287,8 @@ public:
|
||||||
|
|
||||||
SVal RetrieveObjCIvar(const GRState *state, const ObjCIvarRegion *R);
|
SVal RetrieveObjCIvar(const GRState *state, const ObjCIvarRegion *R);
|
||||||
|
|
||||||
|
SVal RetrieveVar(const GRState *state, const VarRegion *R);
|
||||||
|
|
||||||
SVal RetrieveLazySymbol(const GRState *state, const TypedRegion *R);
|
SVal RetrieveLazySymbol(const GRState *state, const TypedRegion *R);
|
||||||
|
|
||||||
SVal CastRetrievedVal(SVal val, const TypedRegion *R, QualType castTy);
|
SVal CastRetrievedVal(SVal val, const TypedRegion *R, QualType castTy);
|
||||||
|
|
@ -847,6 +849,9 @@ SVal RegionStoreManager::Retrieve(const GRState *state, Loc L, QualType T) {
|
||||||
|
|
||||||
if (const ObjCIvarRegion *IVR = dyn_cast<ObjCIvarRegion>(R))
|
if (const ObjCIvarRegion *IVR = dyn_cast<ObjCIvarRegion>(R))
|
||||||
return CastRetrievedVal(RetrieveObjCIvar(state, IVR), IVR, T);
|
return CastRetrievedVal(RetrieveObjCIvar(state, IVR), IVR, T);
|
||||||
|
|
||||||
|
if (const VarRegion *VR = dyn_cast<VarRegion>(R))
|
||||||
|
return CastRetrievedVal(RetrieveVar(state, VR), VR, T);
|
||||||
|
|
||||||
RegionBindingsTy B = GetRegionBindings(state->getStore());
|
RegionBindingsTy B = GetRegionBindings(state->getStore());
|
||||||
RegionBindingsTy::data_type* V = B.lookup(R);
|
RegionBindingsTy::data_type* V = B.lookup(R);
|
||||||
|
|
@ -859,16 +864,6 @@ SVal RegionStoreManager::Retrieve(const GRState *state, Loc L, QualType T) {
|
||||||
// the value it had upon its creation and/or entry to the analyzed
|
// the value it had upon its creation and/or entry to the analyzed
|
||||||
// function/method. These are either symbolic values or 'undefined'.
|
// function/method. These are either symbolic values or 'undefined'.
|
||||||
|
|
||||||
// We treat function parameters as symbolic values.
|
|
||||||
if (const VarRegion* VR = dyn_cast<VarRegion>(R)) {
|
|
||||||
const VarDecl *VD = VR->getDecl();
|
|
||||||
|
|
||||||
if (VD == SelfDecl)
|
|
||||||
return loc::MemRegionVal(getSelfRegion(0));
|
|
||||||
|
|
||||||
if (VR->hasGlobalsOrParametersStorage())
|
|
||||||
return ValMgr.getRegionValueSymbolValOrUnknown(VR, VD->getType());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (R->hasHeapOrStackStorage()) {
|
if (R->hasHeapOrStackStorage()) {
|
||||||
// All stack variables are considered to have undefined values
|
// All stack variables are considered to have undefined values
|
||||||
|
|
@ -1023,6 +1018,27 @@ SVal RegionStoreManager::RetrieveObjCIvar(const GRState* state,
|
||||||
return RetrieveLazySymbol(state, R);
|
return RetrieveLazySymbol(state, R);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SVal RegionStoreManager::RetrieveVar(const GRState *state,
|
||||||
|
const VarRegion *R) {
|
||||||
|
|
||||||
|
// Check if the region has a binding.
|
||||||
|
RegionBindingsTy B = GetRegionBindings(state->getStore());
|
||||||
|
|
||||||
|
if (const SVal* V = B.lookup(R))
|
||||||
|
return *V;
|
||||||
|
|
||||||
|
// Lazily derive a value for the VarRegion.
|
||||||
|
const VarDecl *VD = R->getDecl();
|
||||||
|
|
||||||
|
if (VD == SelfDecl)
|
||||||
|
return loc::MemRegionVal(getSelfRegion(0));
|
||||||
|
|
||||||
|
if (R->hasGlobalsOrParametersStorage())
|
||||||
|
return ValMgr.getRegionValueSymbolValOrUnknown(R, VD->getType());
|
||||||
|
|
||||||
|
return UndefinedVal();
|
||||||
|
}
|
||||||
|
|
||||||
SVal RegionStoreManager::RetrieveLazySymbol(const GRState *state,
|
SVal RegionStoreManager::RetrieveLazySymbol(const GRState *state,
|
||||||
const TypedRegion *R) {
|
const TypedRegion *R) {
|
||||||
|
|
||||||
|
|
@ -1093,7 +1109,15 @@ SVal RegionStoreManager::RetrieveArray(const GRState *state,
|
||||||
SVal RegionStoreManager::CastRetrievedVal(SVal V, const TypedRegion *R,
|
SVal RegionStoreManager::CastRetrievedVal(SVal V, const TypedRegion *R,
|
||||||
QualType castTy) {
|
QualType castTy) {
|
||||||
|
|
||||||
if (castTy.isNull() || R->getValueType(getContext()) == castTy)
|
if (castTy.isNull())
|
||||||
|
return V;
|
||||||
|
|
||||||
|
ASTContext &Ctx = getContext();
|
||||||
|
QualType valTy = R->getValueType(Ctx);
|
||||||
|
castTy = Ctx.getCanonicalType(castTy);
|
||||||
|
|
||||||
|
|
||||||
|
if (valTy == castTy)
|
||||||
return V;
|
return V;
|
||||||
|
|
||||||
return ValMgr.getSValuator().EvalCast(V, castTy);
|
return ValMgr.getSValuator().EvalCast(V, castTy);
|
||||||
|
|
|
||||||
|
|
@ -48,9 +48,27 @@ SVal SimpleSValuator::EvalCastNL(NonLoc val, QualType castTy) {
|
||||||
|
|
||||||
bool isLocType = Loc::IsLocType(castTy);
|
bool isLocType = Loc::IsLocType(castTy);
|
||||||
|
|
||||||
if (isLocType)
|
if (nonloc::LocAsInteger *LI = dyn_cast<nonloc::LocAsInteger>(&val)) {
|
||||||
if (nonloc::LocAsInteger *LI = dyn_cast<nonloc::LocAsInteger>(&val))
|
if (isLocType)
|
||||||
return LI->getLoc();
|
return LI->getLoc();
|
||||||
|
|
||||||
|
ASTContext &Ctx = ValMgr.getContext();
|
||||||
|
|
||||||
|
// FIXME: Support promotions/truncations.
|
||||||
|
if (Ctx.getTypeSize(castTy) == Ctx.getTypeSize(Ctx.VoidPtrTy))
|
||||||
|
return val;
|
||||||
|
|
||||||
|
return UnknownVal();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const SymExpr *se = val.getAsSymbolicExpression()) {
|
||||||
|
ASTContext &Ctx = ValMgr.getContext();
|
||||||
|
QualType T = Ctx.getCanonicalType(se->getType(Ctx));
|
||||||
|
if (T == Ctx.getCanonicalType(castTy))
|
||||||
|
return val;
|
||||||
|
|
||||||
|
return UnknownVal();
|
||||||
|
}
|
||||||
|
|
||||||
if (!isa<nonloc::ConcreteInt>(val))
|
if (!isa<nonloc::ConcreteInt>(val))
|
||||||
return UnknownVal();
|
return UnknownVal();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue