From 06911d4e88b1a6ca7ec3b2d8e234e679a4c09ff9 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Thu, 22 Mar 2012 06:29:41 +0000 Subject: [PATCH] "Teach" RetainCountChecker about dispatch_set_context, which can indirectly free its argument later. Fixes . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@153244 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Checkers/RetainCountChecker.cpp | 8 ++++++++ test/Analysis/objc-arc.m | 17 +++++++++++++++++ 2 files changed, 25 insertions(+) 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") { + // - 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() { } } +// - 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; +} -- 2.40.0