[analyzer] Fix a bug in region store that lead to undefined value false

positives.

The includeSuffix was only set on the first iteration through the
function, resulting in invalid regions being produced by getLazyBinding
(ex: zoomRegion.y).

llvm-svn: 174016
This commit is contained in:
Anna Zaks 2013-01-31 01:19:52 +00:00
parent c7cd308274
commit 3a86267192
2 changed files with 21 additions and 17 deletions

View File

@ -489,8 +489,7 @@ public: // Part of public interface to class.
/// Get the state and region whose binding this region R corresponds to.
std::pair<Store, const MemRegion*>
getLazyBinding(RegionBindingsConstRef B, const MemRegion *R,
const MemRegion *originalRegion,
bool includeSuffix = false);
const MemRegion *originalRegion);
//===------------------------------------------------------------------===//
// State pruning.
@ -1220,9 +1219,7 @@ SVal RegionStoreManager::getBinding(RegionBindingsConstRef B, Loc L, QualType T)
std::pair<Store, const MemRegion *>
RegionStoreManager::getLazyBinding(RegionBindingsConstRef B,
const MemRegion *R,
const MemRegion *originalRegion,
bool includeSuffix) {
const MemRegion *originalRegion) {
if (originalRegion != R) {
if (Optional<SVal> OV = B.getDefaultBinding(R)) {
if (const nonloc::LazyCompoundVal *V =
@ -1244,10 +1241,8 @@ RegionStoreManager::getLazyBinding(RegionBindingsConstRef B,
getLazyBinding(B, FR->getSuperRegion(), originalRegion);
if (X.second) {
if (includeSuffix)
return std::make_pair(X.first,
MRMgr.getFieldRegionWithSuper(FR, X.second));
return X;
return std::make_pair(X.first,
MRMgr.getFieldRegionWithSuper(FR, X.second));
}
}
@ -1259,11 +1254,9 @@ RegionStoreManager::getLazyBinding(RegionBindingsConstRef B,
getLazyBinding(B, baseReg->getSuperRegion(), originalRegion);
if (X.second) {
if (includeSuffix)
return std::make_pair(X.first,
MRMgr.getCXXBaseObjectRegionWithSuper(baseReg,
X.second));
return X;
return std::make_pair(X.first,
MRMgr.getCXXBaseObjectRegionWithSuper(baseReg,
X.second));
}
}
@ -1408,8 +1401,7 @@ RegionStoreManager::getBindingForFieldOrElementCommon(RegionBindingsConstRef B,
// Lazy binding?
Store lazyBindingStore = NULL;
const MemRegion *lazyBindingRegion = NULL;
llvm::tie(lazyBindingStore, lazyBindingRegion) = getLazyBinding(B, R, R,
true);
llvm::tie(lazyBindingStore, lazyBindingRegion) = getLazyBinding(B, R, R);
if (lazyBindingRegion)
return getLazyBinding(lazyBindingRegion,
getRegionBindings(lazyBindingStore));

View File

@ -253,6 +253,19 @@ int testStructFieldChainsNested(int index, int anotherIndex) {
return 0;
}
typedef struct {
int zoomLevel;
struct point center;
} Outer;
extern int test13116945(struct point x);
static void radar13116945(struct point centerCoordinate) {
Outer zoomRegion;
zoomRegion.zoomLevel = 0;
zoomRegion.center = centerCoordinate;
Outer r = zoomRegion;
test13116945(r.center); // no-warning
}
// --------------------
// False positives
@ -289,4 +302,3 @@ void testFieldChainIsNotEnough(int index) {
// FIXME: Should be TRUE.
clang_analyzer_eval(vals[index].a[0].x == 42); // expected-warning{{UNKNOWN}}
}