From fe12f88924a507fbae5a2eb6000f0a40283d6602 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Tue, 21 Jul 2009 00:12:07 +0000 Subject: [PATCH] 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 --- clang/lib/Analysis/RegionStore.cpp | 46 ++++++++++++++++++++------ clang/lib/Analysis/SimpleSValuator.cpp | 22 ++++++++++-- 2 files changed, 55 insertions(+), 13 deletions(-) diff --git a/clang/lib/Analysis/RegionStore.cpp b/clang/lib/Analysis/RegionStore.cpp index 247c6040c817..2ea2b88df2c6 100644 --- a/clang/lib/Analysis/RegionStore.cpp +++ b/clang/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/clang/lib/Analysis/SimpleSValuator.cpp b/clang/lib/Analysis/SimpleSValuator.cpp index 4f8c29c0710c..7462fe65fe8f 100644 --- a/clang/lib/Analysis/SimpleSValuator.cpp +++ b/clang/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(); -- 2.34.1