From: Ted Kremenek Date: Tue, 21 Jul 2009 00:12:07 +0000 (+0000) Subject: RegionStore: X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9031dd7a989f893be0c3a9d8915b1218646be763;p=clang 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76516 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp index 247c6040c8..2ea2b88df2 100644 --- a/lib/Analysis/RegionStore.cpp +++ b/lib/Analysis/RegionStore.cpp @@ -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(R)) return CastRetrievedVal(RetrieveObjCIvar(state, IVR), IVR, T); + + if (const VarRegion *VR = dyn_cast(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(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); diff --git a/lib/Analysis/SimpleSValuator.cpp b/lib/Analysis/SimpleSValuator.cpp index 4f8c29c071..7462fe65fe 100644 --- a/lib/Analysis/SimpleSValuator.cpp +++ b/lib/Analysis/SimpleSValuator.cpp @@ -48,9 +48,27 @@ SVal SimpleSValuator::EvalCastNL(NonLoc val, QualType castTy) { bool isLocType = Loc::IsLocType(castTy); - if (isLocType) - if (nonloc::LocAsInteger *LI = dyn_cast(&val)) + if (nonloc::LocAsInteger *LI = dyn_cast(&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(val)) return UnknownVal();