Switch RegionStore over to using <BaseRegion+raw offset> to store
value bindings.  Along with a small change to OSAtomicChecker, this
resolves <rdar://problem/7527292> and resolves some long-standing
issues with how values can be bound to the same physical address by
not have the same "key".  This change is only a beginning; logically
RegionStore needs to better handle loads from addresses where the
stored value is larger/smaller/different type than the loaded value.
We handle these cases in an approximate fashion now (via
CastRetrievedVal and help in SimpleSValuator), but it could be made
much smarter.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93137 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/Store.cpp b/lib/Analysis/Store.cpp
index 4d15023..fd44a80 100644
--- a/lib/Analysis/Store.cpp
+++ b/lib/Analysis/Store.cpp
@@ -197,23 +197,29 @@
 /// CastRetrievedVal - Used by subclasses of StoreManager to implement
 ///  implicit casts that arise from loads from regions that are reinterpreted
 ///  as another region.
-SVal  StoreManager::CastRetrievedVal(SVal V, const TypedRegion *R,
-                                     QualType castTy) {
+SVal StoreManager::CastRetrievedVal(SVal V, const TypedRegion *R,
+                                    QualType castTy, bool performTestOnly) {
   
-#ifndef NDEBUG
   if (castTy.isNull())
     return V;
   
   ASTContext &Ctx = ValMgr.getContext();
-  QualType T = R->getValueType(Ctx);
 
-  // Automatically translate references to pointers.
-  if (const ReferenceType *RT = T->getAs<ReferenceType>())
-    T = Ctx.getPointerType(RT->getPointeeType());
-
-  assert(ValMgr.getContext().hasSameUnqualifiedType(castTy, T));
-#endif
-
+  if (performTestOnly) {  
+    // Automatically translate references to pointers.
+    QualType T = R->getValueType(Ctx);
+    if (const ReferenceType *RT = T->getAs<ReferenceType>())
+      T = Ctx.getPointerType(RT->getPointeeType());
+    
+    assert(ValMgr.getContext().hasSameUnqualifiedType(castTy, T));
+    return V;
+  }
+  
+  if (const Loc *L = dyn_cast<Loc>(&V))
+    return ValMgr.getSValuator().EvalCastL(*L, castTy);
+  else if (const NonLoc *NL = dyn_cast<NonLoc>(&V))
+    return ValMgr.getSValuator().EvalCastNL(*NL, castTy);
+  
   return V;
 }