diff options
Diffstat (limited to 'lib/Analysis/CFRefCount.cpp')
-rw-r--r-- | lib/Analysis/CFRefCount.cpp | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp index 8be76d8289..1021574de6 100644 --- a/lib/Analysis/CFRefCount.cpp +++ b/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. |