From 6e86cafca3e3c68692cf0bb4496807ad7e092f9b Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Fri, 24 Apr 2009 18:00:17 +0000 Subject: [PATCH] retain/release checker: more hacks to workaround false positives cause by delegates. When a reference counted object is passed as to a 'void*' argument to a method stop tracking the reference count. llvm-svn: 69984 --- clang/lib/Analysis/CFRefCount.cpp | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/clang/lib/Analysis/CFRefCount.cpp b/clang/lib/Analysis/CFRefCount.cpp index 8be76d828975..1021574de608 100644 --- a/clang/lib/Analysis/CFRefCount.cpp +++ b/clang/lib/Analysis/CFRefCount.cpp @@ -1076,9 +1076,28 @@ RetainSummaryManager::getInitMethodSummary(ObjCMessageExpr* ME) { RetainSummary* RetainSummaryManager::getCommonMethodSummary(ObjCMessageExpr* ME, const char *s) { + if (ObjCMethodDecl *MD = ME->getMethodDecl()) { + // Scan the method decl for 'void*' arguments. These should be treated + // as 'StopTracking' because they are often used with delegates. + // Delegates are a frequent form of false positives with the retain + // count checker. + unsigned i = 0; + for (ObjCMethodDecl::param_iterator I = MD->param_begin(), + E = MD->param_end(); I != E; ++I, ++i) + if (ParmVarDecl *PD = *I) { + QualType Ty = Ctx.getCanonicalType(PD->getType()); + if (Ty.getUnqualifiedType() == Ctx.VoidPtrTy) + ScratchArgs.push_back(std::make_pair(i, StopTracking)); + } + } + // Look for methods that return an owned object. - if (!isTrackedObjectType(ME->getType())) - return 0; + if (!isTrackedObjectType(ME->getType())) { + if (ScratchArgs.empty()) + return 0; + + return getPersistentSummary(RetEffect::MakeNoRet()); + } // EXPERIMENTAL: Assume the Cocoa conventions for all objects returned // by instance methods.