diff options
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/RegionStore.cpp | 16 | ||||
-rw-r--r-- | clang/test/Analysis/malloc.c | 16 |
2 files changed, 24 insertions, 8 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp index cc3ea8c3bf5..e849333f94e 100644 --- a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp +++ b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp @@ -1274,7 +1274,15 @@ SVal RegionStoreManager::getBindingForFieldOrElementCommon(Store store, // At this point we have already checked in either getBindingForElement or // getBindingForField if 'R' has a direct binding. RegionBindings B = GetRegionBindings(store); + + // Lazy binding? + Store lazyBindingStore = NULL; + const MemRegion *lazyBindingRegion = NULL; + llvm::tie(lazyBindingStore, lazyBindingRegion) = GetLazyBinding(B, R, R); + if (lazyBindingRegion) + return getLazyBinding(lazyBindingRegion, lazyBindingStore); + // Record whether or not we see a symbolic index. That can completely // be out of scope of our lookup. bool hasSymbolicIndex = false; @@ -1299,14 +1307,6 @@ SVal RegionStoreManager::getBindingForFieldOrElementCommon(Store store, break; } - // Lazy binding? - Store lazyBindingStore = NULL; - const MemRegion *lazyBindingRegion = NULL; - llvm::tie(lazyBindingStore, lazyBindingRegion) = GetLazyBinding(B, R, R); - - if (lazyBindingRegion) - return getLazyBinding(lazyBindingRegion, lazyBindingStore); - if (R->hasStackNonParametersStorage()) { if (isa<ElementRegion>(R)) { // Currently we don't reason specially about Clang-style vectors. Check diff --git a/clang/test/Analysis/malloc.c b/clang/test/Analysis/malloc.c index 3b4712320b7..32c6171f8c4 100644 --- a/clang/test/Analysis/malloc.c +++ b/clang/test/Analysis/malloc.c @@ -760,6 +760,22 @@ void radar10978247_positive(int myValueSize) { return; } +// <rdar://problem/11269741> Previously this triggered a false positive +// because malloc() is known to return uninitialized memory and the binding +// of 'o' to 'p->n' was not getting propertly handled. Now we report a leak. +struct rdar11269741_a_t { + struct rdar11269741_b_t { + int m; + } n; +}; + +int rdar11269741(struct rdar11269741_b_t o) +{ + struct rdar11269741_a_t *p = (struct rdar11269741_a_t *) malloc(sizeof(*p)); + p->n = o; + return p->n.m; // expected-warning {{leak}} +} + // ---------------------------------------------------------------------------- // Below are the known false positives. |