aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/CFRefCount.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2009-04-24 18:00:17 +0000
committerTed Kremenek <kremenek@apple.com>2009-04-24 18:00:17 +0000
commit376d1e72c31c8b362eb3a035751c662140a7e5d7 (patch)
tree2809985886ad2d1a55983299b65bc30baec79259 /lib/Analysis/CFRefCount.cpp
parent2e09bf6d02405b5cd9c4223fd11519a089032a66 (diff)
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69984 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/CFRefCount.cpp')
-rw-r--r--lib/Analysis/CFRefCount.cpp23
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.