aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Analysis/PathSensitive/Store.h8
-rw-r--r--lib/Analysis/BasicStore.cpp10
-rw-r--r--lib/Analysis/RegionStore.cpp14
-rw-r--r--lib/Analysis/Store.cpp16
-rw-r--r--test/Analysis/misc-ps.m9
5 files changed, 39 insertions, 18 deletions
diff --git a/include/clang/Analysis/PathSensitive/Store.h b/include/clang/Analysis/PathSensitive/Store.h
index ffc3e24196..51143ec84b 100644
--- a/include/clang/Analysis/PathSensitive/Store.h
+++ b/include/clang/Analysis/PathSensitive/Store.h
@@ -177,10 +177,16 @@ public:
/// iterBindings - Iterate over the bindings in the Store.
virtual void iterBindings(Store store, BindingsHandler& f) = 0;
-private:
+protected:
CastResult MakeElementRegion(const GRState *state, const MemRegion *region,
QualType pointeeTy, QualType castToTy,
uint64_t index = 0);
+
+ /// CastRetrievedVal - Used by subclasses of StoreManager to implement
+ /// implicit casts that arise from loads from regions that are reinterpreted
+ /// as another region.
+ SValuator::CastResult CastRetrievedVal(SVal val, const GRState *state,
+ const TypedRegion *R, QualType castTy);
};
// FIXME: Do we still need this?
diff --git a/lib/Analysis/BasicStore.cpp b/lib/Analysis/BasicStore.cpp
index cb2af0f537..e211339658 100644
--- a/lib/Analysis/BasicStore.cpp
+++ b/lib/Analysis/BasicStore.cpp
@@ -271,7 +271,7 @@ SValuator::CastResult BasicStoreManager::Retrieve(const GRState *state,
if (isa<UnknownVal>(loc))
return SValuator::CastResult(state, UnknownVal());
- assert (!isa<UndefinedVal>(loc));
+ assert(!isa<UndefinedVal>(loc));
switch (loc.getSubKind()) {
@@ -296,8 +296,12 @@ SValuator::CastResult BasicStoreManager::Retrieve(const GRState *state,
return SValuator::CastResult(state, UnknownVal());
BindingsTy B = GetBindings(state->getStore());
- BindingsTy::data_type* T = B.lookup(R);
- return SValuator::CastResult(state, T ? *T : UnknownVal());
+ BindingsTy::data_type *Val = B.lookup(R);
+
+ if (!Val)
+ break;
+
+ return CastRetrievedVal(*Val, state, cast<TypedRegion>(R), T);
}
case loc::ConcreteIntKind:
diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp
index 53ef054c53..9225bfbaae 100644
--- a/lib/Analysis/RegionStore.cpp
+++ b/lib/Analysis/RegionStore.cpp
@@ -299,9 +299,6 @@ public:
SVal RetrieveFieldOrElementCommon(const GRState *state, const TypedRegion *R,
QualType Ty, const MemRegion *superR);
- SValuator::CastResult CastRetrievedVal(SVal val, const GRState *state,
- const TypedRegion *R, QualType castTy);
-
/// Retrieve the values in a struct and return a CompoundVal, used when doing
/// struct copy:
/// struct s x, y;
@@ -1247,17 +1244,6 @@ SVal RegionStoreManager::RetrieveArray(const GRState *state,
#endif
}
-SValuator::CastResult RegionStoreManager::CastRetrievedVal(SVal V,
- const GRState *state,
- const TypedRegion *R,
- QualType castTy) {
- if (castTy.isNull())
- return SValuator::CastResult(state, V);
-
- ASTContext &Ctx = getContext();
- return ValMgr.getSValuator().EvalCast(V, state, castTy, R->getValueType(Ctx));
-}
-
//===----------------------------------------------------------------------===//
// Binding values to regions.
//===----------------------------------------------------------------------===//
diff --git a/lib/Analysis/Store.cpp b/lib/Analysis/Store.cpp
index fca69e69cb..e2412f6e28 100644
--- a/lib/Analysis/Store.cpp
+++ b/lib/Analysis/Store.cpp
@@ -197,3 +197,19 @@ StoreManager::CastRegion(const GRState *state, const MemRegion* R,
return CastResult(state, R);
}
+
+
+/// CastRetrievedVal - Used by subclasses of StoreManager to implement
+/// implicit casts that arise from loads from regions that are reinterpreted
+/// as another region.
+SValuator::CastResult StoreManager::CastRetrievedVal(SVal V,
+ const GRState *state,
+ const TypedRegion *R,
+ QualType castTy) {
+ if (castTy.isNull())
+ return SValuator::CastResult(state, V);
+
+ ASTContext &Ctx = ValMgr.getContext();
+ return ValMgr.getSValuator().EvalCast(V, state, castTy, R->getValueType(Ctx));
+}
+
diff --git a/test/Analysis/misc-ps.m b/test/Analysis/misc-ps.m
index 1ca209dbf8..e74877748b 100644
--- a/test/Analysis/misc-ps.m
+++ b/test/Analysis/misc-ps.m
@@ -533,3 +533,12 @@ int test_array_compound(int *q, int *r, int *z) {
return j;
}
+// This test case previously crashed with -analyzer-store=basic because the
+// symbolic value stored in 'x' wouldn't be implicitly casted to a signed value
+// during the comparison.
+int rdar_7124210(unsigned int x) {
+ enum { SOME_CONSTANT = 123 };
+ int compare = ((signed) SOME_CONSTANT) == *((signed *) &x);
+ return compare ? 0 : 1; // Forces the evaluation of the symbolic constraint.
+}
+