retain/release checker: Hook up attributes 'objc_ownership_retain' and

'objc_ownership_release' to the effects on receivers.

llvm-svn: 70507
This commit is contained in:
Ted Kremenek 2009-04-30 20:00:31 +00:00
parent aae83b4596
commit 2ff8a79d27
2 changed files with 35 additions and 10 deletions

View File

@ -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<ObjCOwnershipReturnsAttr>()) {
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<ObjCOwnershipRetainAttr>()) {
ScratchArgs.push_back(std::make_pair(i, IncRefMsg));
hasArgEffect = true;
hasEffect = true;
}
else if ((*I)->getAttr<ObjCOwnershipCFRetainAttr>()) {
ScratchArgs.push_back(std::make_pair(i, IncRef));
hasArgEffect = true;
hasEffect = true;
}
else if ((*I)->getAttr<ObjCOwnershipReleaseAttr>()) {
ScratchArgs.push_back(std::make_pair(i, DecRefMsg));
hasArgEffect = true;
hasEffect = true;
}
else if ((*I)->getAttr<ObjCOwnershipCFReleaseAttr>()) {
ScratchArgs.push_back(std::make_pair(i, DecRef));
hasArgEffect = true;
hasEffect = true;
}
else if ((*I)->getAttr<ObjCOwnershipMakeCollectableAttr>()) {
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<ObjCOwnershipRetainAttr>()) {
ReceiverEff = IncRefMsg;
hasEffect = true;
}
else if (MD->getAttr<ObjCOwnershipReleaseAttr>()) {
ReceiverEff = DecRefMsg;
hasEffect = true;
}
if (!hasEffect)
return 0;
return getPersistentSummary(RE);
return getPersistentSummary(RE, ReceiverEff);
}
RetainSummary*

View File

@ -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];
}
//===----------------------------------------------------------------------===//
// <rdar://problem/6833332>
// One build of the analyzer accidentally stopped tracking the allocated