aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/RegionStore.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2009-07-20 22:58:02 +0000
committerTed Kremenek <kremenek@apple.com>2009-07-20 22:58:02 +0000
commit25c545788da6e3a725206cfa378b9b83a7da6024 (patch)
treeb76ba656bf8be257935bcb76946e19439bddeefc /lib/Analysis/RegionStore.cpp
parent76ed9cb1d7398bb721cb9df67b3004c14dae8aa8 (diff)
Enhanced IsReinterpreted() (RegionStore.cpp) to reason about higher-order
pointers. Enhanced RegionStoreManager::Retrieve() to handle automatic casts when the loaded value is different from the requested value. This should be refined over time, but essentially we should always symbolicate locations as locations, and convert them to non-locations on demand. These changes now cause 'misc-ps.m' to pass again. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76497 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/RegionStore.cpp')
-rw-r--r--lib/Analysis/RegionStore.cpp61
1 files changed, 48 insertions, 13 deletions
diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp
index 0d2467f55e..247c6040c8 100644
--- a/lib/Analysis/RegionStore.cpp
+++ b/lib/Analysis/RegionStore.cpp
@@ -286,6 +286,10 @@ public:
SVal RetrieveField(const GRState *state, const FieldRegion *R);
SVal RetrieveObjCIvar(const GRState *state, const ObjCIvarRegion *R);
+
+ SVal RetrieveLazySymbol(const GRState *state, const TypedRegion *R);
+
+ SVal CastRetrievedVal(SVal val, const TypedRegion *R, QualType castTy);
/// Retrieve the values in a struct and return a CompoundVal, used when doing
/// struct copy:
@@ -758,7 +762,20 @@ static bool IsReinterpreted(QualType RTy, QualType UsedTy, ASTContext &Ctx) {
if (RTy == UsedTy)
return false;
- return !(Loc::IsLocType(RTy) && Loc::IsLocType(UsedTy));
+
+ // Recursively check the types. We basically want to see if a pointer value
+ // is ever reinterpreted as a non-pointer, e.g. void** and intptr_t*
+ // represents a reinterpretation.
+ if (Loc::IsLocType(RTy) && Loc::IsLocType(UsedTy)) {
+ const PointerType *PRTy = RTy->getAsPointerType();
+ const PointerType *PUsedTy = UsedTy->getAsPointerType();
+
+ return PUsedTy && PRTy &&
+ IsReinterpreted(PRTy->getPointeeType(),
+ PUsedTy->getPointeeType(), Ctx);
+ }
+
+ return true;
}
SVal RegionStoreManager::Retrieve(const GRState *state, Loc L, QualType T) {
@@ -823,11 +840,14 @@ SVal RegionStoreManager::Retrieve(const GRState *state, Loc L, QualType T) {
return UnknownVal();
if (const FieldRegion* FR = dyn_cast<FieldRegion>(R))
- return RetrieveField(state, FR);
+ return CastRetrievedVal(RetrieveField(state, FR), FR, T);
if (const ElementRegion* ER = dyn_cast<ElementRegion>(R))
- return RetrieveElement(state, ER);
+ return CastRetrievedVal(RetrieveElement(state, ER), ER, T);
+ if (const ObjCIvarRegion *IVR = dyn_cast<ObjCIvarRegion>(R))
+ return CastRetrievedVal(RetrieveObjCIvar(state, IVR), IVR, T);
+
RegionBindingsTy B = GetRegionBindings(state->getStore());
RegionBindingsTy::data_type* V = B.lookup(R);
@@ -835,9 +855,6 @@ SVal RegionStoreManager::Retrieve(const GRState *state, Loc L, QualType T) {
if (V)
return *V;
- 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
// function/method. These are either symbolic values or 'undefined'.
@@ -986,8 +1003,6 @@ SVal RegionStoreManager::RetrieveField(const GRState* state,
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());
@@ -1005,18 +1020,29 @@ SVal RegionStoreManager::RetrieveObjCIvar(const GRState* state,
return UnknownVal();
}
+ return RetrieveLazySymbol(state, R);
+}
+
+SVal RegionStoreManager::RetrieveLazySymbol(const GRState *state,
+ const TypedRegion *R) {
+
+ QualType valTy = R->getValueType(getContext());
+
// 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();
+ if (const QualType *ty = state->get<RegionCasts>(R)) {
+ if (const PointerType *PT = (*ty)->getAsPointerType()) {
+ QualType castTy = PT->getPointeeType();
+
+ if (!IsReinterpreted(valTy, castTy, getContext()))
+ valTy = castTy;
+ }
}
// All other values are symbolic.
- return ValMgr.getRegionValueSymbolValOrUnknown(R, Ty);
+ return ValMgr.getRegionValueSymbolValOrUnknown(R, valTy);
}
-
SVal RegionStoreManager::RetrieveStruct(const GRState *state,
const TypedRegion* R){
QualType T = R->getValueType(getContext());
@@ -1064,6 +1090,15 @@ SVal RegionStoreManager::RetrieveArray(const GRState *state,
return ValMgr.makeCompoundVal(T, ArrayVal);
}
+SVal RegionStoreManager::CastRetrievedVal(SVal V, const TypedRegion *R,
+ QualType castTy) {
+
+ if (castTy.isNull() || R->getValueType(getContext()) == castTy)
+ return V;
+
+ return ValMgr.getSValuator().EvalCast(V, castTy);
+}
+
//===----------------------------------------------------------------------===//
// Binding values to regions.
//===----------------------------------------------------------------------===//