summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorZhongxing Xu <xuzhongxing@gmail.com>2009-06-18 06:29:10 +0000
committerZhongxing Xu <xuzhongxing@gmail.com>2009-06-18 06:29:10 +0000
commitcea657807873815709ab4db9c76f31334af6dbd8 (patch)
tree1c92c19f632e38eda5348ba68f3caac8622c4f9b /clang
parente7e659431c231be662dd954d66a18fdc9914e27a (diff)
downloadbcm5719-llvm-cea657807873815709ab4db9c76f31334af6dbd8.tar.gz
bcm5719-llvm-cea657807873815709ab4db9c76f31334af6dbd8.zip
When casting region, if we do not create an element region, record the cast-to
type. When retrieving the region value, if we are going to create a symbol value, use the cast-to type if possible. llvm-svn: 73690
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Analysis/PathSensitive/ValueManager.h2
-rw-r--r--clang/lib/Analysis/RegionStore.cpp24
-rw-r--r--clang/lib/Analysis/SVals.cpp5
-rw-r--r--clang/test/Analysis/casts.c16
4 files changed, 38 insertions, 9 deletions
diff --git a/clang/include/clang/Analysis/PathSensitive/ValueManager.h b/clang/include/clang/Analysis/PathSensitive/ValueManager.h
index 89af975de7a..b86f4e87530 100644
--- a/clang/include/clang/Analysis/PathSensitive/ValueManager.h
+++ b/clang/include/clang/Analysis/PathSensitive/ValueManager.h
@@ -81,7 +81,7 @@ public:
SVal makeZeroArrayIndex();
/// GetRegionValueSymbolVal - make a unique symbol for value of R.
- SVal getRegionValueSymbolVal(const MemRegion* R);
+ SVal getRegionValueSymbolVal(const MemRegion* R, QualType T = QualType());
SVal getConjuredSymbolVal(const Expr *E, unsigned Count);
SVal getConjuredSymbolVal(const Expr* E, QualType T, unsigned Count);
diff --git a/clang/lib/Analysis/RegionStore.cpp b/clang/lib/Analysis/RegionStore.cpp
index d67fa84c713..af8c7c9a9b2 100644
--- a/clang/lib/Analysis/RegionStore.cpp
+++ b/clang/lib/Analysis/RegionStore.cpp
@@ -584,6 +584,7 @@ SVal RegionStoreManager::getSizeInElements(const GRState *state,
QualType VarTy = VR->getValueType(getContext());
uint64_t EleSize = getContext().getTypeSize(EleTy);
uint64_t VarSize = getContext().getTypeSize(VarTy);
+ assert(VarSize != 0);
return NonLoc::MakeIntVal(getBasicVals(), VarSize / EleSize, false);
}
@@ -710,15 +711,18 @@ RegionStoreManager::CastRegion(const GRState *state, const MemRegion* R,
uint64_t ObjTySize = getContext().getTypeSize(ObjTy);
if ((PointeeTySize > 0 && PointeeTySize < ObjTySize) ||
- (ObjTy->isAggregateType() && PointeeTy->isScalarType())) {
+ (ObjTy->isAggregateType() && PointeeTy->isScalarType()) ||
+ ObjTySize == 0 /* R has 'void*' type. */) {
// Record the cast type of the region.
state = setCastType(state, R, ToTy);
SVal Idx = ValMgr.makeZeroArrayIndex();
ElementRegion* ER = MRMgr.getElementRegion(PointeeTy, Idx,R,getContext());
return CastResult(state, ER);
- } else
+ } else {
+ state = setCastType(state, R, ToTy);
return CastResult(state, R);
+ }
}
if (isa<ObjCObjectRegion>(R)) {
@@ -930,14 +934,22 @@ SVal RegionStoreManager::Retrieve(const GRState *state, Loc L, QualType T) {
return UndefinedVal();
}
+ // 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();
+ }
+
// All other integer values are symbolic.
if (Loc::IsLocType(RTy) || RTy->isIntegerType())
- return ValMgr.getRegionValueSymbolVal(R);
+ return ValMgr.getRegionValueSymbolVal(R, RTy);
else
return UnknownVal();
}
-SVal RegionStoreManager::RetrieveStruct(const GRState *state, const TypedRegion* R){
+SVal RegionStoreManager::RetrieveStruct(const GRState *state,
+ const TypedRegion* R){
QualType T = R->getValueType(getContext());
assert(T->isStructureType());
@@ -1220,8 +1232,8 @@ const GRState *RegionStoreManager::RemoveRegionView(const GRState *state,
return state->set<RegionViewMap>(Base, RVFactory.Remove(*d, View));
}
-const GRState *RegionStoreManager::setCastType(const GRState *state, const MemRegion* R,
- QualType T) {
+const GRState *RegionStoreManager::setCastType(const GRState *state,
+ const MemRegion* R, QualType T) {
return state->set<RegionCasts>(R, T);
}
diff --git a/clang/lib/Analysis/SVals.cpp b/clang/lib/Analysis/SVals.cpp
index e19b16867b3..285d51e506c 100644
--- a/clang/lib/Analysis/SVals.cpp
+++ b/clang/lib/Analysis/SVals.cpp
@@ -322,11 +322,12 @@ NonLoc NonLoc::MakeCompoundVal(QualType T, llvm::ImmutableList<SVal> Vals,
return nonloc::CompoundVal(BasicVals.getCompoundValData(T, Vals));
}
-SVal ValueManager::getRegionValueSymbolVal(const MemRegion* R) {
+SVal ValueManager::getRegionValueSymbolVal(const MemRegion* R, QualType T) {
SymbolRef sym = SymMgr.getRegionValueSymbol(R);
if (const TypedRegion* TR = dyn_cast<TypedRegion>(R)) {
- QualType T = TR->getValueType(SymMgr.getContext());
+ if (!T.getTypePtr())
+ T = TR->getValueType(SymMgr.getContext());
// If T is of function pointer type, create a CodeTextRegion wrapping a
// symbol.
diff --git a/clang/test/Analysis/casts.c b/clang/test/Analysis/casts.c
index 94a1eac0a31..c5fcdd92e1c 100644
--- a/clang/test/Analysis/casts.c
+++ b/clang/test/Analysis/casts.c
@@ -14,3 +14,19 @@ void f(int sock) {
;
}
}
+
+struct s {
+ struct s *value;
+};
+
+// ElementRegion and cast-to pointee type may be of the same size:
+// 'struct s **' and 'int'.
+
+int f1(struct s **pval) {
+ int *tbool = ((void*)0);
+ struct s *t = *pval;
+ pval = &(t->value);
+ tbool = (int *)pval;
+ char c = (unsigned char) *tbool;
+}
+
OpenPOWER on IntegriCloud