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 661f84f..fa355f5 100644
--- a/lib/Analysis/RegionStore.cpp
+++ b/lib/Analysis/RegionStore.cpp
@@ -281,9 +281,11 @@
/// 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 @@
if (V)
return *V;
- if (const ObjCIvarRegion *IVR = dyn_cast<ObjCIvarRegion>(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<ObjCIvarRegion>(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 @@
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<RegionCasts>(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());