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;
+ }
+}