From: Ted Kremenek Date: Tue, 9 Feb 2010 19:11:53 +0000 (+0000) Subject: Fix lookup of fields from lazy bindings to check if the region is X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8ec4aac6d3dee698e4cb7b9f540d962e4ccab468;p=clang 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95679 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Checker/RegionStore.cpp b/lib/Checker/RegionStore.cpp index c08be0cff6..a6646436d5 100644 --- a/lib/Checker/RegionStore.cpp +++ b/lib/Checker/RegionStore.cpp @@ -1054,7 +1054,7 @@ RegionStoreManager::GetLazyBinding(RegionBindings B, const MemRegion *R) { const std::pair &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 &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(R)) - return RetrieveElement(lazyBindingStore, - cast(lazyBindingRegion)); - + if (lazyBindingRegion) { + if (const ElementRegion *ER = dyn_cast(lazyBindingRegion)) + return RetrieveElement(lazyBindingStore, ER); return RetrieveField(lazyBindingStore, cast(lazyBindingRegion)); } diff --git a/test/Analysis/misc-ps.m b/test/Analysis/misc-ps.m index 20eed9cb3d..fa05f6f603 100644 --- a/test/Analysis/misc-ps.m +++ b/test/Analysis/misc-ps.m @@ -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 +}