aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/Store.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Analysis/Store.cpp')
-rw-r--r--lib/Analysis/Store.cpp16
1 files changed, 10 insertions, 6 deletions
diff --git a/lib/Analysis/Store.cpp b/lib/Analysis/Store.cpp
index 2910f49c80..bbda565cec 100644
--- a/lib/Analysis/Store.cpp
+++ b/lib/Analysis/Store.cpp
@@ -238,16 +238,20 @@ const GRState *StoreManager::InvalidateRegion(const GRState *state,
}
const TypedRegion *TR = cast<TypedRegion>(R);
+ QualType T = TR->getValueType(Ctx);
- QualType T;
-
- // If the region is cast to another type, use that type.
+ // If the region is cast to another type, use that type.
if (const QualType *CastTy = getCastType(state, R)) {
assert(!(*CastTy)->isObjCObjectPointerType());
- T = (*CastTy)->getAsPointerType()->getPointeeType();
- } else
- T = TR->getValueType(Ctx);
+ QualType NewT = (*CastTy)->getAsPointerType()->getPointeeType();
+ // The only exception is if the original region had a location type as its
+ // value type we always want to treat the region as binding to a location.
+ // This issue can arise when pointers are casted to integers and back.
+ if (!Loc::IsLocType(T) || Loc::IsLocType(NewT))
+ T = NewT;
+ }
+
if (Loc::IsLocType(T) || (T->isIntegerType() && T->isScalarType())) {
SVal V = ValMgr.getConjuredSymbolVal(E, T, Count);
return Bind(state, ValMgr.makeLoc(TR), V);