Use canonical type for building ElementRegion. Otherwise ElementRegions cannot
be unique.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@73482 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Analysis/PathSensitive/MemRegion.h b/include/clang/Analysis/PathSensitive/MemRegion.h
index 0e8da2a..8afcc4c 100644
--- a/include/clang/Analysis/PathSensitive/MemRegion.h
+++ b/include/clang/Analysis/PathSensitive/MemRegion.h
@@ -620,7 +620,7 @@
   /// getElementRegion - Retrieve the memory region associated with the
   ///  associated element type, index, and super region.
   ElementRegion* getElementRegion(QualType elementType, SVal Idx,
-                                  const MemRegion* superRegion);
+                                  const MemRegion* superRegion,ASTContext &Ctx);
 
   /// getFieldRegion - Retrieve or create the memory region associated with
   ///  a specified FieldDecl.  'superRegion' corresponds to the containing
diff --git a/lib/Analysis/BasicStore.cpp b/lib/Analysis/BasicStore.cpp
index 2dd46c3..ba4c021 100644
--- a/lib/Analysis/BasicStore.cpp
+++ b/lib/Analysis/BasicStore.cpp
@@ -248,7 +248,7 @@
   
   if (BaseR)  
     return Loc::MakeVal(MRMgr.getElementRegion(elementType, UnknownVal(),
-                                               BaseR));
+                                               BaseR, getContext()));
   else
     return UnknownVal();
 }
diff --git a/lib/Analysis/MemRegion.cpp b/lib/Analysis/MemRegion.cpp
index 9f066f4..9e11a26 100644
--- a/lib/Analysis/MemRegion.cpp
+++ b/lib/Analysis/MemRegion.cpp
@@ -296,10 +296,12 @@
 
 ElementRegion*
 MemRegionManager::getElementRegion(QualType elementType, SVal Idx,
-                                   const MemRegion* superRegion){
+                                 const MemRegion* superRegion, ASTContext& Ctx){
+
+  QualType T = Ctx.getCanonicalType(elementType);
 
   llvm::FoldingSetNodeID ID;
-  ElementRegion::ProfileRegion(ID, elementType, Idx, superRegion);
+  ElementRegion::ProfileRegion(ID, T, Idx, superRegion);
 
   void* InsertPos;
   MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
@@ -307,7 +309,7 @@
 
   if (!R) {
     R = (ElementRegion*) A.Allocate<ElementRegion>();
-    new (R) ElementRegion(elementType, Idx, superRegion);
+    new (R) ElementRegion(T, Idx, superRegion);
     Regions.InsertNode(R, InsertPos);
   }
 
diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp
index eae3aef..d20c70a 100644
--- a/lib/Analysis/RegionStore.cpp
+++ b/lib/Analysis/RegionStore.cpp
@@ -438,7 +438,7 @@
       }
     }
     return loc::MemRegionVal(MRMgr.getElementRegion(elementType, Offset,
-                                                    BaseRegion));
+                                                    BaseRegion, getContext()));
   }
   
   SVal BaseIdx = ElemR->getIndex();
@@ -473,7 +473,8 @@
   else
     NewIdx = nonloc::ConcreteInt(getBasicVals().getValue(BaseIdxI + OffI));
 
-  return loc::MemRegionVal(MRMgr.getElementRegion(elementType, NewIdx, ArrayR));
+  return loc::MemRegionVal(MRMgr.getElementRegion(elementType, NewIdx, ArrayR,
+						  getContext()));
 }
 
 SVal RegionStoreManager::getSizeInElements(const GRState* St,
@@ -560,7 +561,7 @@
   T = AT->getElementType();
   
   nonloc::ConcreteInt Idx(getBasicVals().getZeroWithPtrWidth(false));
-  ElementRegion* ER = MRMgr.getElementRegion(T, Idx, ArrayR);
+  ElementRegion* ER = MRMgr.getElementRegion(T, Idx, ArrayR, getContext());
   
   return loc::MemRegionVal(ER);                    
 }
@@ -622,7 +623,7 @@
       state = setCastType(state, R, ToTy);
 
       SVal Idx = ValMgr.makeZeroArrayIndex();
-      ElementRegion* ER = MRMgr.getElementRegion(PointeeTy, Idx, R);
+      ElementRegion* ER = MRMgr.getElementRegion(PointeeTy, Idx,R,getContext());
       return CastResult(state, ER);
     } else
       return CastResult(state, R);
@@ -654,7 +655,7 @@
     QualType EleTy = T->getAsPointerType()->getPointeeType();
 
     SVal ZeroIdx = ValMgr.makeZeroArrayIndex();
-    ER = MRMgr.getElementRegion(EleTy, ZeroIdx, SR);
+    ER = MRMgr.getElementRegion(EleTy, ZeroIdx, SR, getContext());
   } 
   else if (const AllocaRegion *AR = dyn_cast<AllocaRegion>(MR)) {
     // Get the alloca region's current cast type.
@@ -664,7 +665,7 @@
     assert(T && "alloca region has no type.");
     QualType EleTy = cast<PointerType>(T->getTypePtr())->getPointeeType();
     SVal ZeroIdx = ValMgr.makeZeroArrayIndex();
-    ER = MRMgr.getElementRegion(EleTy, ZeroIdx, AR);
+    ER = MRMgr.getElementRegion(EleTy, ZeroIdx, AR, getContext());
   } 
   else
     ER = cast<ElementRegion>(MR);
@@ -686,7 +687,8 @@
                                                            Offset->getValue()));
     SVal NewIdx = Base->EvalBinOp(getBasicVals(), Op, OffConverted);
     const MemRegion* NewER =
-      MRMgr.getElementRegion(ER->getElementType(), NewIdx,ER->getSuperRegion());
+      MRMgr.getElementRegion(ER->getElementType(), NewIdx,ER->getSuperRegion(),
+			     getContext());
     return Loc::MakeVal(NewER);
 
   }
@@ -871,7 +873,8 @@
 
   for (; i < Size; ++i) {
     SVal Idx = NonLoc::MakeVal(getBasicVals(), i);
-    ElementRegion* ER = MRMgr.getElementRegion(CAT->getElementType(), Idx, R);
+    ElementRegion* ER = MRMgr.getElementRegion(CAT->getElementType(), Idx, R,
+					       getContext());
     QualType ETy = ER->getElementType();
     SVal ElementVal = Retrieve(St, loc::MemRegionVal(ER), ETy);
     ArrayVal = getBasicVals().consVals(ElementVal, ArrayVal);
@@ -1153,7 +1156,7 @@
       SVal Idx = NonLoc::MakeVal(getBasicVals(), i);
       ElementRegion* ER =
         MRMgr.getElementRegion(cast<ArrayType>(T)->getElementType(),
-                               Idx, R);
+                               Idx, R, getContext());
 
       SVal V = NonLoc::MakeVal(getBasicVals(), str[j], sizeof(char)*8, true);
       St = Bind(St, loc::MemRegionVal(ER), V);
@@ -1173,7 +1176,7 @@
     SVal Idx = NonLoc::MakeVal(getBasicVals(), i);
     ElementRegion* ER =
       MRMgr.getElementRegion(cast<ArrayType>(T)->getElementType(),
-                             Idx, R);
+                             Idx, R, getContext());
 
     if (CAT->getElementType()->isStructureType())
       St = BindStruct(St, ER, *VI);
diff --git a/lib/Analysis/Store.cpp b/lib/Analysis/Store.cpp
index 13326ab..5aa756e 100644
--- a/lib/Analysis/Store.cpp
+++ b/lib/Analysis/Store.cpp
@@ -90,7 +90,8 @@
         // FIXME: Is this the right thing to do in all cases?
         const TypedRegion *Base = isa<ElementRegion>(TR) ?
                                   cast<TypedRegion>(TR->getSuperRegion()) : TR;
-        ElementRegion* ER = MRMgr.getElementRegion(Pointee, Idx, Base);
+        ElementRegion* ER = MRMgr.getElementRegion(Pointee, Idx, Base, 
+						   StateMgr.getContext());
         return CastResult(state, ER);
       }
     }
diff --git a/test/Analysis/elementtype.c b/test/Analysis/elementtype.c
new file mode 100644
index 0000000..10328e6
--- /dev/null
+++ b/test/Analysis/elementtype.c
@@ -0,0 +1,13 @@
+// RUN: clang-cc -analyze -checker-simple -analyzer-store=region %s
+
+typedef struct added_obj_st {
+  int type;
+} ADDED_OBJ;
+
+// Test if we are using the canonical type for ElementRegion.
+void f() {
+  ADDED_OBJ *ao[4]={((void*)0),((void*)0),((void*)0),((void*)0)};
+  if (ao[0] != ((void*)0))   {
+    ao[0]->type=0;
+  }
+}