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:
Ted Kremenek 2009-07-21 00:12:07 +00:00
parent 05ac8276cf
commit fe12f88924
2 changed files with 55 additions and 13 deletions

View File

@ -287,6 +287,8 @@ public:
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 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))
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::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
// 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()) {
// All stack variables are considered to have undefined values
@ -1023,6 +1018,27 @@ SVal RegionStoreManager::RetrieveObjCIvar(const GRState* state,
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,
const TypedRegion *R) {
@ -1093,7 +1109,15 @@ SVal RegionStoreManager::RetrieveArray(const GRState *state,
SVal RegionStoreManager::CastRetrievedVal(SVal V, const TypedRegion *R,
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 ValMgr.getSValuator().EvalCast(V, castTy);

View File

@ -48,9 +48,27 @@ SVal SimpleSValuator::EvalCastNL(NonLoc val, QualType 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();
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))
return UnknownVal();