From 8f40afbf7740c39fccaa4b8cc5aa2814d5ed6fdc Mon Sep 17 00:00:00 2001 From: Ted Kremenek <kremenek@apple.com> Date: Thu, 26 Apr 2012 05:08:26 +0000 Subject: [PATCH] [analyzer] check lazy bindings in RegionStore first before looking for default values. Fixes <rdar://problem/11269741>. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@155615 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/StaticAnalyzer/Core/RegionStore.cpp | 16 ++++++++-------- test/Analysis/malloc.c | 16 ++++++++++++++++ 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/lib/StaticAnalyzer/Core/RegionStore.cpp b/lib/StaticAnalyzer/Core/RegionStore.cpp index cc3ea8c3bf5..e849333f94e 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<ElementRegion>(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 3b4712320b7..32c6171f8c4 100644 --- a/test/Analysis/malloc.c +++ b/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. -- GitLab