forked from OSchip/llvm-project
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:
parent
0ae70d16b8
commit
499b4e3387
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue