From 2cd1293ad32dd5db3f3fcead9720cc2676c088e6 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Thu, 30 Apr 2009 20:00:31 +0000 Subject: [PATCH] retain/release checker: Hook up attributes 'objc_ownership_retain' and 'objc_ownership_release' to the effects on receivers. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70507 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/CFRefCount.cpp | 30 ++++++++++++++++++++---------- test/Analysis/retain-release.m | 15 +++++++++++++++ 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp index eb7d04a342..7ea462a1bb 100644 --- a/lib/Analysis/CFRefCount.cpp +++ b/lib/Analysis/CFRefCount.cpp @@ -1139,14 +1139,14 @@ RetainSummaryManager::getMethodSummaryFromAnnotations(const ObjCMethodDecl *MD){ assert(ScratchArgs.empty()); // Determine if there is a special return effect for this method. - bool hasRetEffect = false; + bool hasEffect = false; RetEffect RE = RetEffect::MakeNoRet(); if (isTrackedObjectType(MD->getResultType())) { if (MD->getAttr()) { RE = isGCEnabled() ? RetEffect::MakeGCNotOwned() : RetEffect::MakeOwned(RetEffect::ObjC, true); - hasRetEffect = true; + hasEffect = true; } else { // Default to 'not owned'. @@ -1155,36 +1155,46 @@ RetainSummaryManager::getMethodSummaryFromAnnotations(const ObjCMethodDecl *MD){ } // Determine if there are any arguments with a specific ArgEffect. - bool hasArgEffect = false; unsigned i = 0; for (ObjCMethodDecl::param_iterator I = MD->param_begin(), E = MD->param_end(); I != E; ++I, ++i) { if ((*I)->getAttr()) { ScratchArgs.push_back(std::make_pair(i, IncRefMsg)); - hasArgEffect = true; + hasEffect = true; } else if ((*I)->getAttr()) { ScratchArgs.push_back(std::make_pair(i, IncRef)); - hasArgEffect = true; + hasEffect = true; } else if ((*I)->getAttr()) { ScratchArgs.push_back(std::make_pair(i, DecRefMsg)); - hasArgEffect = true; + hasEffect = true; } else if ((*I)->getAttr()) { ScratchArgs.push_back(std::make_pair(i, DecRef)); - hasArgEffect = true; + hasEffect = true; } else if ((*I)->getAttr()) { ScratchArgs.push_back(std::make_pair(i, MakeCollectable)); - hasArgEffect = true; + hasEffect = true; } } - if (!hasRetEffect && !hasArgEffect) + // Determine any effects on the receiver. + ArgEffect ReceiverEff = DoNothing; + if (MD->getAttr()) { + ReceiverEff = IncRefMsg; + hasEffect = true; + } + else if (MD->getAttr()) { + ReceiverEff = DecRefMsg; + hasEffect = true; + } + + if (!hasEffect) return 0; - return getPersistentSummary(RE); + return getPersistentSummary(RE, ReceiverEff); } RetainSummary* diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m index d36f985e3a..c01da9cabb 100644 --- a/test/Analysis/retain-release.m +++ b/test/Analysis/retain-release.m @@ -511,6 +511,21 @@ void test_attr_5c(TestOwnershipAttr *X) { [X myCFRelease:str]; } +void test_attr_6a() { + TestOwnershipAttr *X = [TestOwnershipAttr alloc]; // expected-warning{{leak}} +} + +void test_attr_6b() { + TestOwnershipAttr *X = [TestOwnershipAttr alloc]; // no-warning + [X myRelease]; +} + +void test_attr_6c() { + TestOwnershipAttr *X = [TestOwnershipAttr alloc]; // expected-warning{{leak}} + [X myRetain]; + [X myRelease]; +} + //===----------------------------------------------------------------------===// // // One build of the analyzer accidentally stopped tracking the allocated -- 2.40.0