After conversations with Zhongxing Xu and Jordy Rose, refine the logic in

RegionStoreManager::RetrieveElement() that handles indexing into a larger scalar
object to only consult the direct binding of a super region if it is a scalar.
This isn't perfect yet, and a big FIXME is attached to the code.  This causes
the test case for PR 7218 now to pass.

llvm-svn: 105195
This commit is contained in:
Ted Kremenek 2010-05-31 01:22:04 +00:00
parent f3d0436077
commit 4708f5a89b
2 changed files with 25 additions and 20 deletions

View File

@ -1173,27 +1173,33 @@ SVal RegionStoreManager::RetrieveElement(Store store,
}
}
// Check if the immediate super region has a direct binding.
if (const Optional<SVal> &V = getDirectBinding(B, superR)) {
if (SymbolRef parentSym = V->getAsSymbol()) {
return ValMgr.getDerivedRegionValueSymbolVal(parentSym, R);
// Handle the case where we are indexing into a larger scalar object.
// For example, this handles:
// int x = ...
// char *y = &x;
// return *y;
// FIXME: This is a hack, and doesn't do anything really intelligent yet.
const RegionRawOffset &O = R->getAsRawOffset();
if (const TypedRegion *baseR = dyn_cast_or_null<TypedRegion>(O.getRegion())) {
QualType baseT = baseR->getValueType(Ctx);
if (baseT->isScalarType()) {
QualType elemT = R->getElementType();
if (elemT->isScalarType()) {
if (Ctx.getTypeSizeInChars(baseT) >= Ctx.getTypeSizeInChars(elemT)) {
if (const Optional<SVal> &V = getDirectBinding(B, superR)) {
if (SymbolRef parentSym = V->getAsSymbol())
return ValMgr.getDerivedRegionValueSymbolVal(parentSym, R);
if (V->isUnknownOrUndef())
return *V;
// Other cases: give up. We are indexing into a larger object
// that has some value, but we don't know how to handle that yet.
return UnknownVal();
}
}
}
}
if (V->isUnknownOrUndef())
return *V;
// Handle LazyCompoundVals for the immediate super region. Other cases
// are handled in 'RetrieveFieldOrElementCommon'.
if (const nonloc::LazyCompoundVal *LCV =
dyn_cast<nonloc::LazyCompoundVal>(V)) {
R = MRMgr.getElementRegionWithSuper(R, LCV->getRegion());
return RetrieveElement(LCV->getStore(), R);
}
// Other cases: give up.
return UnknownVal();
}
return RetrieveFieldOrElementCommon(store, R, R->getElementType(), superR);
}

View File

@ -1,5 +1,4 @@
// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store region -verify %s
// XFAIL: *
char PR7218(char a) {
char buf[2];
buf[0] = a;