Temporarily disable most use of region casts in RegionStoreManager,
instead preferring to use the a region's actual type when creating
symbols and using the QualType passed to Retrieve for implicit
casting.  This preprocessor logic is temporary; eventually we will
either remove region casts or keep them.

Temporarily toggle (via preprocessor directives) that SymbolicRegions
with heap storage are not undefined, but instead should be
symbolicated.  If we want to model that a SymbolicRegion is
uninitialized, we can explicitly model that by binding UndefinedVal to
that region.  It turns out that we want to treat most heap objects as
being defined, not the other way around.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76720 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp
index dc54c8f..dc0cac8 100644
--- a/lib/Analysis/RegionStore.cpp
+++ b/lib/Analysis/RegionStore.cpp
@@ -27,6 +27,9 @@
 
 using namespace clang;
 
+#define USE_REGION_CASTS 0
+#define HEAP_UNDEFINED 0
+
 // Actual Store type.
 typedef llvm::ImmutableMap<const MemRegion*, SVal> RegionBindingsTy;
 
@@ -679,10 +682,13 @@
     case MemRegion::SymbolicRegionKind: {
       const SymbolicRegion *SR = cast<SymbolicRegion>(MR);
       QualType T;
+#if USE_REGION_CASTS
       // If the SymbolicRegion was cast to another type, use that type.
       if (const QualType *t = state->get<RegionCasts>(SR))
         T = *t;
-      else {
+      else 
+#endif
+      {
         // Otherwise use the symbol's type.
         SymbolRef Sym = SR->getSymbol();
         T = Sym->getType(getContext());
@@ -867,8 +873,11 @@
   // the value it had upon its creation and/or entry to the analyzed
   // function/method.  These are either symbolic values or 'undefined'.
 
-
+#if HEAP_UNDEFINED
   if (R->hasHeapOrStackStorage()) {
+#else
+  if (R->hasStackStorage()) {
+#endif
     // All stack variables are considered to have undefined values
     // upon creation.  All heap allocated blocks are considered to
     // have undefined values as well unless they are explicitly bound
@@ -876,12 +885,14 @@
     return SValuator::CastResult(state, UndefinedVal());
   }
 
+#if USE_REGION_CASTS
   // 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 T = *p;
     RTy = T->getAsPointerType()->getPointeeType();
   }
+#endif
 
   // All other values are symbolic.
   return SValuator::CastResult(state,
@@ -924,19 +935,24 @@
   if (const SVal *V = B.lookup(superR)) {
     if (SymbolRef parentSym = V->getAsSymbol())
       return ValMgr.getDerivedRegionValueSymbolVal(parentSym, R);
+
+    if (V->isUnknownOrUndef())
+      return *V;
     
     // Other cases: give up.
     return UnknownVal();
   }
   
+#if 0
   if (R->hasHeapStorage()) {
-    // FIXME: If the region has heap storage and we know nothing special
-    // about its bindings, should we instead return UnknownVal?  Seems like
-    // we should only return UndefinedVal in the cases where we know the value
-    // will be undefined.
+      // FIXME: If the region has heap storage and we know nothing special
+      // about its bindings, should we instead return UnknownVal?  Seems like
+      // we should only return UndefinedVal in the cases where we know the value
+      // will be undefined.
     return UndefinedVal();
   }
-
+#endif
+  
   if (R->hasStackStorage() && !R->hasParametersStorage()) {
     // Currently we don't reason specially about Clang-style vectors.  Check
     // if superR is a vector and if so return Unknown.
@@ -950,10 +966,12 @@
 
   QualType Ty = R->getValueType(getContext());
 
+#if USE_REGION_CASTS
   // 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))
     Ty = (*p)->getAsPointerType()->getPointeeType();
+#endif
 
   return ValMgr.getRegionValueSymbolValOrUnknown(R, Ty);
 }
@@ -981,19 +999,23 @@
     assert(0 && "Unknown default value");
   }
 
+#if HEAP_UNDEFINED
   // FIXME: Is this correct?  Should it be UnknownVal?
   if (R->hasHeapStorage())
     return UndefinedVal();
+#endif
   
   if (R->hasStackStorage() && !R->hasParametersStorage())
     return UndefinedVal();
 
+#if USE_REGION_CASTS
   // 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();
   }
+#endif
 
   // All other values are symbolic.
   return ValMgr.getRegionValueSymbolValOrUnknown(R, Ty);
@@ -1047,7 +1069,8 @@
                                             const TypedRegion *R) {
   
   QualType valTy = R->getValueType(getContext());
-  
+
+#if USE_REGION_CASTS
   // If the region is already cast to another type, use that type to create the
   // symbol value.
   if (const QualType *ty = state->get<RegionCasts>(R)) {
@@ -1058,6 +1081,7 @@
         valTy = castTy;
     }
   }
+#endif
   
   // All other values are symbolic.
   return ValMgr.getRegionValueSymbolValOrUnknown(R, valTy);