From: Ted Kremenek Date: Wed, 15 Jul 2009 06:09:28 +0000 (+0000) Subject: Enhance RegionStore's reasoning about Objective-C ivars. More testing to follow. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5bd2fe365f29799a78a862df2d1cff365d792b63;p=clang Enhance RegionStore's reasoning about Objective-C ivars. More testing to follow. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@75748 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp index 661f84f4b1..fa355f551c 100644 --- a/lib/Analysis/RegionStore.cpp +++ b/lib/Analysis/RegionStore.cpp @@ -281,9 +281,11 @@ public: /// return symbolic SVal Retrieve(const GRState *state, Loc L, QualType T = QualType()); - SVal RetrieveElement(const GRState* state, const ElementRegion* R); + SVal RetrieveElement(const GRState *state, const ElementRegion *R); - SVal RetrieveField(const GRState* state, const FieldRegion* R); + SVal RetrieveField(const GRState *state, const FieldRegion *R); + + SVal RetrieveObjCIvar(const GRState *state, const ObjCIvarRegion *R); /// Retrieve the values in a struct and return a CompoundVal, used when doing /// struct copy: @@ -865,20 +867,8 @@ SVal RegionStoreManager::Retrieve(const GRState *state, Loc L, QualType T) { if (V) return *V; - if (const ObjCIvarRegion *IVR = dyn_cast(R)) { - const MemRegion *SR = IVR->getSuperRegion(); - - // If the super region is 'self' then return the symbol representing - // the value of the ivar upon entry to the method. - if (SR == SelfRegion) { - // FIXME: Do we need to handle the case where the super region - // has a view? We want to canonicalize the bindings. - return ValMgr.getRegionValueSymbolVal(R); - } - - // Otherwise, we need a new symbol. For now return Unknown. - return UnknownVal(); - } + if (const ObjCIvarRegion *IVR = dyn_cast(R)) + return RetrieveObjCIvar(state, IVR); // The location does not have a bound value. This means that it has // the value it had upon its creation and/or entry to the analyzed @@ -1025,6 +1015,40 @@ SVal RegionStoreManager::RetrieveField(const GRState* state, return ValMgr.getRegionValueSymbolValOrUnknown(R, Ty); } +SVal RegionStoreManager::RetrieveObjCIvar(const GRState* state, + const ObjCIvarRegion* R) { + + QualType Ty = R->getValueType(getContext()); + + // Check if the region has a binding. + RegionBindingsTy B = GetRegionBindings(state->getStore()); + + if (const SVal* V = B.lookup(R)) + return *V; + + const MemRegion *superR = R->getSuperRegion(); + + // Check if the super region has a binding. + if (const SVal *V = B.lookup(superR)) { + if (SymbolRef parentSym = V->getAsSymbol()) + return ValMgr.getDerivedRegionValueSymbolVal(parentSym, R); + + // Other cases: give up. + return UnknownVal(); + } + + // If the region is already cast to another type, use that type to create the + // symbol value. + if (const QualType *p = state->get(R)) { + QualType tmp = *p; + Ty = tmp->getAsPointerType()->getPointeeType(); + } + + // All other values are symbolic. + return ValMgr.getRegionValueSymbolValOrUnknown(R, Ty); +} + + SVal RegionStoreManager::RetrieveStruct(const GRState *state, const TypedRegion* R){ QualType T = R->getValueType(getContext());