From: Ted Kremenek Date: Thu, 26 Apr 2012 05:08:26 +0000 (+0000) Subject: [analyzer] check lazy bindings in RegionStore first before looking for default values... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8f40afbf7740c39fccaa4b8cc5aa2814d5ed6fdc;p=clang [analyzer] check lazy bindings in RegionStore first before looking for default values. Fixes . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@155615 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/StaticAnalyzer/Core/RegionStore.cpp b/lib/StaticAnalyzer/Core/RegionStore.cpp index cc3ea8c3bf..e849333f94 100644 --- a/lib/StaticAnalyzer/Core/RegionStore.cpp +++ b/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(R)) { // Currently we don't reason specially about Clang-style vectors. Check diff --git a/test/Analysis/malloc.c b/test/Analysis/malloc.c index 3b4712320b..32c6171f8c 100644 --- a/test/Analysis/malloc.c +++ b/test/Analysis/malloc.c @@ -760,6 +760,22 @@ void radar10978247_positive(int myValueSize) { return; } +// 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.