[analyzer] Introduce new MemRegion, "TypedValueRegion", so that we can separate TypedRegions that implement getValueType() from those that don't.

Patch by Olaf Krzikalla!

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@137498 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp b/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
index 85d74ac..b2ac9dd 100644
--- a/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
+++ b/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
@@ -290,7 +290,7 @@
   if (!LV)
     return;
 
-  const TypedRegion* R = dyn_cast<TypedRegion>(LV->stripCasts());
+  const TypedValueRegion* R = dyn_cast<TypedValueRegion>(LV->stripCasts());
   if (!R)
     return;
 
diff --git a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
index ca15a74..71c4ee6 100644
--- a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
@@ -770,8 +770,7 @@
 bool CStringChecker::SummarizeRegion(raw_ostream& os, ASTContext& Ctx,
                                      const MemRegion *MR) {
   const TypedRegion *TR = dyn_cast<TypedRegion>(MR);
-  if (!TR)
-    return false;
+  const TypedValueRegion *TVR = dyn_cast<TypedValueRegion>(MR);
 
   switch (TR->getKind()) {
   case MemRegion::FunctionTextRegionKind: {
@@ -790,16 +789,16 @@
     return true;
   case MemRegion::CXXThisRegionKind:
   case MemRegion::CXXTempObjectRegionKind:
-    os << "a C++ temp object of type " << TR->getValueType().getAsString();
+    os << "a C++ temp object of type " << TVR->getValueType().getAsString();
     return true;
   case MemRegion::VarRegionKind:
-    os << "a variable of type" << TR->getValueType().getAsString();
+    os << "a variable of type" << TVR->getValueType().getAsString();
     return true;
   case MemRegion::FieldRegionKind:
-    os << "a field of type " << TR->getValueType().getAsString();
+    os << "a field of type " << TVR->getValueType().getAsString();
     return true;
   case MemRegion::ObjCIvarRegionKind:
-    os << "an instance variable of type " << TR->getValueType().getAsString();
+    os << "an instance variable of type " << TVR->getValueType().getAsString();
     return true;
   default:
     return false;
diff --git a/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp b/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
index 67db2d2..f1e7aaa 100644
--- a/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
@@ -116,7 +116,7 @@
                              MemRegionManager &mrMgr, Store s)
       : C(c), StoreMgr(storeMgr), MrMgr(mrMgr), store(s) {}
 
-      bool Find(const TypedRegion *R) {
+      bool Find(const TypedValueRegion *R) {
         QualType T = R->getValueType();
         if (const RecordType *RT = T->getAsStructureType()) {
           const RecordDecl *RD = RT->getDecl()->getDefinition();
diff --git a/lib/StaticAnalyzer/Checkers/OSAtomicChecker.cpp b/lib/StaticAnalyzer/Checkers/OSAtomicChecker.cpp
index b518ab4..8280131 100644
--- a/lib/StaticAnalyzer/Checkers/OSAtomicChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/OSAtomicChecker.cpp
@@ -106,8 +106,8 @@
   // LoadTy specifying can be omitted. But we put it here to emphasize the 
   // semantics.
   QualType LoadTy;
-  if (const TypedRegion *TR =
-      dyn_cast_or_null<TypedRegion>(location.getAsRegion())) {
+  if (const TypedValueRegion *TR =
+      dyn_cast_or_null<TypedValueRegion>(location.getAsRegion())) {
     LoadTy = TR->getValueType();
   }
   Engine.evalLoad(Tmp, theValueExpr, C.getPredecessor(), 
@@ -159,8 +159,8 @@
       SVal val = stateEqual->getSVal(newValueExpr);
 
       // Handle implicit value casts.
-      if (const TypedRegion *R =
-          dyn_cast_or_null<TypedRegion>(location.getAsRegion())) {
+      if (const TypedValueRegion *R =
+          dyn_cast_or_null<TypedValueRegion>(location.getAsRegion())) {
         val = svalBuilder.evalCast(val,R->getValueType(), newValueExpr->getType());
       }
 
diff --git a/lib/StaticAnalyzer/Core/BasicValueFactory.cpp b/lib/StaticAnalyzer/Core/BasicValueFactory.cpp
index 0ed4ff1..f08c1fd 100644
--- a/lib/StaticAnalyzer/Core/BasicValueFactory.cpp
+++ b/lib/StaticAnalyzer/Core/BasicValueFactory.cpp
@@ -27,7 +27,7 @@
 
 void LazyCompoundValData::Profile(llvm::FoldingSetNodeID& ID,
                                   const StoreRef &store,
-                                  const TypedRegion *region) {
+                                  const TypedValueRegion *region) {
   ID.AddPointer(store.getStore());
   ID.AddPointer(region);
 }
@@ -128,7 +128,7 @@
 
 const LazyCompoundValData*
 BasicValueFactory::getLazyCompoundValData(const StoreRef &store,
-                                          const TypedRegion *region) {
+                                          const TypedValueRegion *region) {
   llvm::FoldingSetNodeID ID;
   LazyCompoundValData::Profile(ID, store, region);
   void* InsertPos;
diff --git a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
index 5f068dc..de4780e 100644
--- a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
+++ b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
@@ -140,7 +140,7 @@
         if (isa<loc::ConcreteInt>(V)) {
           bool b = false;
           if (R->isBoundable()) {
-            if (const TypedRegion *TR = dyn_cast<TypedRegion>(R)) {
+            if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R)) {
               if (TR->getValueType()->isObjCObjectPointerType()) {
                 os << "initialized to nil";
                 b = true;
@@ -170,7 +170,7 @@
       if (isa<loc::ConcreteInt>(V)) {
         bool b = false;
         if (R->isBoundable()) {
-          if (const TypedRegion *TR = dyn_cast<TypedRegion>(R)) {
+          if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R)) {
             if (TR->getValueType()->isObjCObjectPointerType()) {
               os << "nil object reference stored to ";
               b = true;
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index e2c0fc1..9db5557 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1522,8 +1522,8 @@
   // Are we loading from a region?  This actually results in two loads; one
   // to fetch the address of the referenced value and one to fetch the
   // referenced value.
-  if (const TypedRegion *TR =
-        dyn_cast_or_null<TypedRegion>(location.getAsRegion())) {
+  if (const TypedValueRegion *TR =
+        dyn_cast_or_null<TypedValueRegion>(location.getAsRegion())) {
 
     QualType ValTy = TR->getValueType();
     if (const ReferenceType *RT = ValTy->getAs<ReferenceType>()) {
@@ -1894,7 +1894,8 @@
     const GRState *noElems = state->BindExpr(S, FalseV);
     
     if (loc::MemRegionVal *MV = dyn_cast<loc::MemRegionVal>(&elementV))
-      if (const TypedRegion *R = dyn_cast<TypedRegion>(MV->getRegion())) {
+      if (const TypedValueRegion *R = 
+            dyn_cast<TypedValueRegion>(MV->getRegion())) {
         // FIXME: The proper thing to do is to really iterate over the
         //  container.  We will do this with dispatch logic to the store.
         //  For now, just 'conjure' up a symbolic value.
diff --git a/lib/StaticAnalyzer/Core/GRState.cpp b/lib/StaticAnalyzer/Core/GRState.cpp
index efe88ba..525b7c7 100644
--- a/lib/StaticAnalyzer/Core/GRState.cpp
+++ b/lib/StaticAnalyzer/Core/GRState.cpp
@@ -200,7 +200,7 @@
   if (!R->isBoundable())
     return UnknownVal();
 
-  if (const TypedRegion *TR = dyn_cast<TypedRegion>(R)) {
+  if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R)) {
     QualType T = TR->getValueType();
     if (Loc::isLocType(T) || T->isIntegerType())
       return getSVal(R);
diff --git a/lib/StaticAnalyzer/Core/RegionStore.cpp b/lib/StaticAnalyzer/Core/RegionStore.cpp
index 6a039c5..d378f10 100644
--- a/lib/StaticAnalyzer/Core/RegionStore.cpp
+++ b/lib/StaticAnalyzer/Core/RegionStore.cpp
@@ -288,9 +288,9 @@
   }
 
   /// BindStruct - Bind a compound value to a structure.
-  StoreRef BindStruct(Store store, const TypedRegion* R, SVal V);
+  StoreRef BindStruct(Store store, const TypedValueRegion* R, SVal V);
 
-  StoreRef BindArray(Store store, const TypedRegion* R, SVal V);
+  StoreRef BindArray(Store store, const TypedValueRegion* R, SVal V);
 
   /// KillStruct - Set the entire struct to unknown.
   StoreRef KillStruct(Store store, const TypedRegion* R, SVal DefaultVal);
@@ -335,9 +335,9 @@
 
   SVal RetrieveVar(Store store, const VarRegion *R);
 
-  SVal RetrieveLazySymbol(const TypedRegion *R);
+  SVal RetrieveLazySymbol(const TypedValueRegion *R);
 
-  SVal RetrieveFieldOrElementCommon(Store store, const TypedRegion *R,
+  SVal RetrieveFieldOrElementCommon(Store store, const TypedValueRegion *R,
                                     QualType Ty, const MemRegion *superR);
   
   SVal RetrieveLazyBinding(const MemRegion *lazyBindingRegion,
@@ -348,15 +348,16 @@
   /// struct s x, y;
   /// x = y;
   /// y's value is retrieved by this method.
-  SVal RetrieveStruct(Store store, const TypedRegion* R);
+  SVal RetrieveStruct(Store store, const TypedValueRegion* R);
 
-  SVal RetrieveArray(Store store, const TypedRegion* R);
+  SVal RetrieveArray(Store store, const TypedValueRegion* R);
 
   /// Used to lazily generate derived symbols for bindings that are defined
   ///  implicitly by default bindings in a super region.
   Optional<SVal> RetrieveDerivedDefaultValue(RegionBindings B,
                                              const MemRegion *superR,
-                                             const TypedRegion *R, QualType Ty);
+                                             const TypedValueRegion *R, 
+                                             QualType Ty);
 
   /// Get the state and region whose binding this region R corresponds to.
   std::pair<Store, const MemRegion*>
@@ -683,7 +684,7 @@
   if (!baseR->isBoundable())
     return;
 
-  const TypedRegion *TR = cast<TypedRegion>(baseR);
+  const TypedValueRegion *TR = cast<TypedValueRegion>(baseR);
   QualType T = TR->getValueType();
 
     // Invalidate the binding.
@@ -805,7 +806,7 @@
     return UnknownVal();
 
   const MemRegion* R = cast<loc::MemRegionVal>(&Array)->getRegion();
-  const TypedRegion* ArrayR = dyn_cast<TypedRegion>(R);
+  const TypedValueRegion* ArrayR = dyn_cast<TypedValueRegion>(R);
 
   if (!ArrayR)
     return UnknownVal();
@@ -854,7 +855,7 @@
 Optional<SVal> RegionStoreManager::getDefaultBinding(RegionBindings B,
                                                      const MemRegion *R) {
   if (R->isBoundable())
-    if (const TypedRegion *TR = dyn_cast<TypedRegion>(R))
+    if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R))
       if (TR->getValueType()->isUnionType())
         return UnknownVal();
 
@@ -898,7 +899,7 @@
 
   // FIXME: Perhaps this method should just take a 'const MemRegion*' argument
   //  instead of 'Loc', and have the other Loc cases handled at a higher level.
-  const TypedRegion *R = cast<TypedRegion>(MR);
+  const TypedValueRegion *R = cast<TypedValueRegion>(MR);
   QualType RTy = R->getValueType();
 
   // FIXME: We should eventually handle funny addressing.  e.g.:
@@ -1074,7 +1075,8 @@
   if (!O.getRegion())
     return UnknownVal();
   
-  if (const TypedRegion *baseR = dyn_cast_or_null<TypedRegion>(O.getRegion())) {
+  if (const TypedValueRegion *baseR = 
+        dyn_cast_or_null<TypedValueRegion>(O.getRegion())) {
     QualType baseT = baseR->getValueType();
     if (baseT->isScalarType()) {
       QualType elemT = R->getElementType();
@@ -1112,7 +1114,7 @@
 Optional<SVal>
 RegionStoreManager::RetrieveDerivedDefaultValue(RegionBindings B,
                                                 const MemRegion *superR,
-                                                const TypedRegion *R,
+                                                const TypedValueRegion *R,
                                                 QualType Ty) {
 
   if (const Optional<SVal> &D = getDefaultBinding(B, superR)) {
@@ -1146,7 +1148,7 @@
 }
                                         
 SVal RegionStoreManager::RetrieveFieldOrElementCommon(Store store,
-                                                      const TypedRegion *R,
+                                                      const TypedValueRegion *R,
                                                       QualType Ty,
                                                       const MemRegion *superR) {
 
@@ -1181,7 +1183,8 @@
     if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
       // Currently we don't reason specially about Clang-style vectors.  Check
       // if superR is a vector and if so return Unknown.
-      if (const TypedRegion *typedSuperR = dyn_cast<TypedRegion>(superR)) {
+      if (const TypedValueRegion *typedSuperR = 
+            dyn_cast<TypedValueRegion>(superR)) {
         if (typedSuperR->getValueType()->isVectorType())
           return UnknownVal();
       }
@@ -1270,18 +1273,20 @@
   return UndefinedVal();
 }
 
-SVal RegionStoreManager::RetrieveLazySymbol(const TypedRegion *R) {
+SVal RegionStoreManager::RetrieveLazySymbol(const TypedValueRegion *R) {
   // All other values are symbolic.
   return svalBuilder.getRegionValueSymbolVal(R);
 }
 
-SVal RegionStoreManager::RetrieveStruct(Store store, const TypedRegion* R) {
+SVal RegionStoreManager::RetrieveStruct(Store store, 
+                                        const TypedValueRegion* R) {
   QualType T = R->getValueType();
   assert(T->isStructureOrClassType());
   return svalBuilder.makeLazyCompoundVal(StoreRef(store, *this), R);
 }
 
-SVal RegionStoreManager::RetrieveArray(Store store, const TypedRegion * R) {
+SVal RegionStoreManager::RetrieveArray(Store store, 
+                                       const TypedValueRegion * R) {
   assert(Ctx.getAsConstantArrayType(R->getValueType()));
   return svalBuilder.makeLazyCompoundVal(StoreRef(store, *this), R);
 }
@@ -1325,14 +1330,14 @@
   const MemRegion *R = cast<loc::MemRegionVal>(L).getRegion();
 
   // Check if the region is a struct region.
-  if (const TypedRegion* TR = dyn_cast<TypedRegion>(R))
+  if (const TypedValueRegion* TR = dyn_cast<TypedValueRegion>(R))
     if (TR->getValueType()->isStructureOrClassType())
       return BindStruct(store, TR, V);
 
   if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
     if (ER->getIndex().isZeroConstant()) {
-      if (const TypedRegion *superR =
-            dyn_cast<TypedRegion>(ER->getSuperRegion())) {
+      if (const TypedValueRegion *superR =
+            dyn_cast<TypedValueRegion>(ER->getSuperRegion())) {
         QualType superTy = superR->getValueType();
         // For now, just invalidate the fields of the struct/union/class.
         // This is for test rdar_test_7185607 in misc-ps-region-store.m.
@@ -1412,7 +1417,7 @@
                              V).getRootWithoutRetain(), *this);
 }
 
-StoreRef RegionStoreManager::BindArray(Store store, const TypedRegion* R,
+StoreRef RegionStoreManager::BindArray(Store store, const TypedValueRegion* R,
                                        SVal Init) {
 
   const ArrayType *AT =cast<ArrayType>(Ctx.getCanonicalType(R->getValueType()));
@@ -1471,7 +1476,7 @@
   return newStore;
 }
 
-StoreRef RegionStoreManager::BindStruct(Store store, const TypedRegion* R,
+StoreRef RegionStoreManager::BindStruct(Store store, const TypedValueRegion* R,
                                         SVal V) {
 
   if (!Features.supportsFields())
diff --git a/lib/StaticAnalyzer/Core/SValBuilder.cpp b/lib/StaticAnalyzer/Core/SValBuilder.cpp
index 71f2b4a..5269ebe 100644
--- a/lib/StaticAnalyzer/Core/SValBuilder.cpp
+++ b/lib/StaticAnalyzer/Core/SValBuilder.cpp
@@ -70,7 +70,7 @@
 }
 
 DefinedOrUnknownSVal 
-SValBuilder::getRegionValueSymbolVal(const TypedRegion* region) {
+SValBuilder::getRegionValueSymbolVal(const TypedValueRegion* region) {
   QualType T = region->getValueType();
 
   if (!SymbolManager::canSymbolicate(T))
@@ -133,7 +133,7 @@
 
 DefinedOrUnknownSVal
 SValBuilder::getDerivedRegionValueSymbolVal(SymbolRef parentSymbol,
-                                             const TypedRegion *region) {
+                                             const TypedValueRegion *region) {
   QualType T = region->getValueType();
 
   if (!SymbolManager::canSymbolicate(T))
diff --git a/lib/StaticAnalyzer/Core/Store.cpp b/lib/StaticAnalyzer/Core/Store.cpp
index a132e6d..8913343 100644
--- a/lib/StaticAnalyzer/Core/Store.cpp
+++ b/lib/StaticAnalyzer/Core/Store.cpp
@@ -87,7 +87,7 @@
 
   // Handle casts from compatible types.
   if (R->isBoundable())
-    if (const TypedRegion *TR = dyn_cast<TypedRegion>(R)) {
+    if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R)) {
       QualType ObjTy = Ctx.getCanonicalType(TR->getValueType());
       if (CanonPointeeTy == ObjTy)
         return R;
@@ -157,7 +157,7 @@
         // Edge case: we are at 0 bytes off the beginning of baseR.  We
         // check to see if type we are casting to is the same as the base
         // region.  If so, just return the base region.
-        if (const TypedRegion *TR = dyn_cast<TypedRegion>(baseR)) {
+        if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(baseR)) {
           QualType ObjTy = Ctx.getCanonicalType(TR->getValueType());
           QualType CanonPointeeTy = Ctx.getCanonicalType(PointeeTy);
           if (CanonPointeeTy == ObjTy)
@@ -211,7 +211,7 @@
 /// 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,
+SVal StoreManager::CastRetrievedVal(SVal V, const TypedValueRegion *R,
                                     QualType castTy, bool performTestOnly) {
   
   if (castTy.isNull())
diff --git a/lib/StaticAnalyzer/Core/SymbolManager.cpp b/lib/StaticAnalyzer/Core/SymbolManager.cpp
index ba8504c..a2fdf28 100644
--- a/lib/StaticAnalyzer/Core/SymbolManager.cpp
+++ b/lib/StaticAnalyzer/Core/SymbolManager.cpp
@@ -90,7 +90,7 @@
 }
 
 const SymbolRegionValue*
-SymbolManager::getRegionValueSymbol(const TypedRegion* R) {
+SymbolManager::getRegionValueSymbol(const TypedValueRegion* R) {
   llvm::FoldingSetNodeID profile;
   SymbolRegionValue::Profile(profile, R);
   void* InsertPos;
@@ -125,7 +125,7 @@
 
 const SymbolDerived*
 SymbolManager::getDerivedSymbol(SymbolRef parentSymbol,
-                                const TypedRegion *R) {
+                                const TypedValueRegion *R) {
 
   llvm::FoldingSetNodeID profile;
   SymbolDerived::Profile(profile, parentSymbol, R);