diff options
author | Ted Kremenek <kremenek@apple.com> | 2012-03-22 06:29:41 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2012-03-22 06:29:41 +0000 |
commit | 06911d4e88b1a6ca7ec3b2d8e234e679a4c09ff9 (patch) | |
tree | bd9835d0312cf95d26fbc90d591f3111fece2f88 | |
parent | 8bd37f1197b3137e6541fe032dfad2d9bf1d76fe (diff) |
"Teach" RetainCountChecker about dispatch_set_context, which can indirectly free its argument later. Fixes <rdar://problem/11059275>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@153244 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp | 8 | ||||
-rw-r--r-- | test/Analysis/objc-arc.m | 17 |
2 files changed, 25 insertions, 0 deletions
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp index 4f21c2a16b..940228e679 100644 --- a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp @@ -985,6 +985,14 @@ const RetainSummary * RetainSummaryManager::getSummary(const FunctionDecl *FD) { // correctly. ScratchArgs = AF.add(ScratchArgs, 12, StopTracking); S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing); + } else if (FName == "dispatch_set_context") { + // <rdar://problem/11059275> - The analyzer currently doesn't have + // a good way to reason about the finalizer function for libdispatch. + // If we pass a context object that is memory managed, stop tracking it. + // FIXME: this hack should possibly go away once we can handle + // libdispatch finalizers. + ScratchArgs = AF.add(ScratchArgs, 1, StopTracking); + S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing); } // Did we get a summary? diff --git a/test/Analysis/objc-arc.m b/test/Analysis/objc-arc.m index a5bf05f38a..e6c6ab5461 100644 --- a/test/Analysis/objc-arc.m +++ b/test/Analysis/objc-arc.m @@ -200,4 +200,21 @@ void test_objc_arrays() { } } +// <rdar://problem/11059275> - dispatch_set_context and ARC. +__attribute__((cf_returns_retained)) CFTypeRef CFBridgingRetain(id X); +typedef void* dispatch_object_t; +void dispatch_set_context(dispatch_object_t object, const void *context); + +void rdar11059275(dispatch_object_t object) { + NSObject *o = [[NSObject alloc] init]; + dispatch_set_context(object, CFBridgingRetain(o)); // no-warning +} +void rdar11059275_positive() { + NSObject *o = [[NSObject alloc] init]; // expected-warning {{leak}} + CFBridgingRetain(o); +} +void rdar11059275_negative() { + NSObject *o = [[NSObject alloc] init]; // no-warning + (void) o; +} |