aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2012-05-02 00:15:40 +0000
committerAnna Zaks <ganna@apple.com>2012-05-02 00:15:40 +0000
commite7958da55ec0ec66e56b6beed6c6ce24dbdc4075 (patch)
tree3738738d1881bff9ddef0a54ab7ec7a5656ecc58
parent12f3297fbef1673b32c8987da9933687996c65b3 (diff)
[analyzer] RetainRelease: Self assignment should not suppress a leak
warning. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@155966 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp6
-rw-r--r--test/Analysis/retain-release.m5
2 files changed, 10 insertions, 1 deletions
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
index 2a97e1c24a..3bd7ae4322 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
@@ -3347,7 +3347,11 @@ void RetainCountChecker::checkBind(SVal loc, SVal val, const Stmt *S,
// To test (3), generate a new state with the binding added. If it is
// the same state, then it escapes (since the store cannot represent
// the binding).
- escapes = (state == (state->bindLoc(*regionLoc, val)));
+ // Do this only if we know that the store is not supposed to generate the
+ // same state.
+ SVal StoredVal = state->getSVal(regionLoc->getRegion());
+ if (StoredVal != val)
+ escapes = (state == (state->bindLoc(*regionLoc, val)));
}
if (!escapes) {
// Case 4: We do not currently model what happens when a symbol is
diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m
index 3aa2656c62..54af13d2a3 100644
--- a/test/Analysis/retain-release.m
+++ b/test/Analysis/retain-release.m
@@ -1305,6 +1305,11 @@ void testattr2_b() {
TestOwnershipAttr *x = [[TestOwnershipAttr alloc] pseudoInit]; // expected-warning{{leak}}
}
+void testattr2_b_11358224_self_assign_looses_the_leak() {
+ TestOwnershipAttr *x = [[TestOwnershipAttr alloc] pseudoInit];// expected-warning{{leak}}
+ x = x;
+}
+
void testattr2_c() {
TestOwnershipAttr *x = [[TestOwnershipAttr alloc] pseudoInit]; // no-warning
[x release];