Fix lookup of fields from lazy bindings to check if the region is

NULL, not the store, to determine if a lookup succeeded.  The store
can be null if it contained no bindings.  This fixes a false positive
reported to me by a user of the analyzer.

llvm-svn: 95679
This commit is contained in:
Ted Kremenek 2010-02-09 19:11:53 +00:00
parent 0ae70d16b8
commit 499b4e3387
2 changed files with 23 additions and 9 deletions

View File

@ -1054,7 +1054,7 @@ RegionStoreManager::GetLazyBinding(RegionBindings B, const MemRegion *R) {
const std::pair<Store, const MemRegion *> &X =
GetLazyBinding(B, ER->getSuperRegion());
if (X.first)
if (X.second)
return std::make_pair(X.first,
MRMgr.getElementRegionWithSuper(ER, X.second));
}
@ -1062,7 +1062,7 @@ RegionStoreManager::GetLazyBinding(RegionBindings B, const MemRegion *R) {
const std::pair<Store, const MemRegion *> &X =
GetLazyBinding(B, FR->getSuperRegion());
if (X.first)
if (X.second)
return std::make_pair(X.first,
MRMgr.getFieldRegionWithSuper(FR, X.second));
}
@ -1179,13 +1179,9 @@ SVal RegionStoreManager::RetrieveFieldOrElementCommon(Store store,
const MemRegion *lazyBindingRegion = NULL;
llvm::tie(lazyBindingStore, lazyBindingRegion) = GetLazyBinding(B, R);
if (lazyBindingStore) {
assert(lazyBindingRegion && "Lazy-binding region not set");
if (isa<ElementRegion>(R))
return RetrieveElement(lazyBindingStore,
cast<ElementRegion>(lazyBindingRegion));
if (lazyBindingRegion) {
if (const ElementRegion *ER = dyn_cast<ElementRegion>(lazyBindingRegion))
return RetrieveElement(lazyBindingStore, ER);
return RetrieveField(lazyBindingStore,
cast<FieldRegion>(lazyBindingRegion));
}

View File

@ -915,3 +915,21 @@ void rdar7582031_test_static_init_zero_b() {
int *p = 0;
*p = 0xDEADBEEF;
}
//===----------------------------------------------------------------------===//
// Test handling of parameters that are structs that contain floats and //
// nested fields. //
//===----------------------------------------------------------------------===//
struct s_rev95547_nested { float x, y; };
struct s_rev95547 {
struct s_rev95547_nested z1;
struct s_rev95547_nested z2;
};
float foo_rev95547(struct s_rev95547 w) {
return w.z1.x + 20.0; // no-warning
}
void foo_rev95547_b(struct s_rev95547 w) {
struct s_rev95547 w2 = w;
w2.z1.x += 20.0; // no-warning
}