Add two new checker-specific attributes: 'objc_ownership_release' and

'objc_ownership_cfrelease'. These are the 'release' equivalents of
'objc_ownership_retain' and 'objc_ownership_cfretain' respectively.

llvm-svn: 70235
This commit is contained in:
Ted Kremenek 2009-04-27 19:36:56 +00:00
parent bfa037705e
commit 84bfa2c2dc
9 changed files with 70 additions and 8 deletions

View File

@ -51,9 +51,11 @@ public:
NonNull,
ObjCException,
ObjCNSObject,
ObjCOwnershipRetain, // Clang/Checker-specific.
ObjCOwnershipCFRetain, // Clang/Checker-specific.
ObjCOwnershipReturns, // Clang/Checker-specific.
ObjCOwnershipCFRelease, // Clang/Checker-specific.
ObjCOwnershipCFRetain, // Clang/Checker-specific.
ObjCOwnershipRelease, // Clang/Checker-specific.
ObjCOwnershipRetain, // Clang/Checker-specific.
ObjCOwnershipReturns, // Clang/Checker-specific.
Overloadable, // Clang-specific
Packed,
Pure,
@ -601,6 +603,8 @@ public:\
};
// Checker-specific attributes.
DEF_SIMPLE_ATTR(ObjCOwnershipCFRelease)
DEF_SIMPLE_ATTR(ObjCOwnershipRelease)
DEF_SIMPLE_ATTR(ObjCOwnershipCFRetain)
DEF_SIMPLE_ATTR(ObjCOwnershipRetain)
DEF_SIMPLE_ATTR(ObjCOwnershipReturns)

View File

@ -76,9 +76,11 @@ public:
AT_nothrow,
AT_nsobject,
AT_objc_exception,
AT_objc_ownership_cfretain, // Clang-specific.
AT_objc_ownership_retain, // Clang-specific.
AT_objc_ownership_returns, // Clang-specific.
AT_objc_ownership_cfrelease, // Clang-specific.
AT_objc_ownership_cfretain, // Clang-specific.
AT_objc_ownership_release, // Clang-specific.
AT_objc_ownership_retain, // Clang-specific.
AT_objc_ownership_returns, // Clang-specific.
AT_objc_gc,
AT_overloadable, // Clang-specific.
AT_packed,

View File

@ -1112,7 +1112,15 @@ RetainSummaryManager::getMethodSummaryFromAnnotations(ObjCMethodDecl *MD) {
else if ((*I)->getAttr<ObjCOwnershipCFRetainAttr>()) {
ScratchArgs.push_back(std::make_pair(i, IncRef));
hasArgEffect = true;
}
}
else if ((*I)->getAttr<ObjCOwnershipReleaseAttr>()) {
ScratchArgs.push_back(std::make_pair(i, DecRefMsg));
hasArgEffect = true;
}
else if ((*I)->getAttr<ObjCOwnershipCFReleaseAttr>()) {
ScratchArgs.push_back(std::make_pair(i, DecRef));
hasArgEffect = true;
}
}
if (!hasRetEffect && !hasArgEffect)

View File

@ -475,6 +475,8 @@ Attr *PCHReader::ReadAttributes() {
SIMPLE_ATTR(ObjCException);
SIMPLE_ATTR(ObjCNSObject);
SIMPLE_ATTR(ObjCOwnershipCFRelease);
SIMPLE_ATTR(ObjCOwnershipRelease);
SIMPLE_ATTR(ObjCOwnershipCFRetain);
SIMPLE_ATTR(ObjCOwnershipRetain);
SIMPLE_ATTR(ObjCOwnershipReturns);

View File

@ -1539,6 +1539,8 @@ void PCHWriter::WriteAttributeRecord(const Attr *Attr) {
case Attr::ObjCException:
case Attr::ObjCNSObject:
case Attr::ObjCOwnershipCFRelease:
case Attr::ObjCOwnershipRelease:
case Attr::ObjCOwnershipCFRetain:
case Attr::ObjCOwnershipRetain:
case Attr::ObjCOwnershipReturns:

View File

@ -140,6 +140,8 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) {
case 22:
if (!memcmp(Str, "objc_ownership_returns", 22))
return AT_objc_ownership_returns;
if (!memcmp(Str, "objc_ownership_release", 22))
return AT_objc_ownership_release;
if (!memcmp(Str, "no_instrument_function", 22))
return AT_no_instrument_function;
break;
@ -147,6 +149,10 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) {
if (!memcmp(Str, "objc_ownership_cfretain", 23))
return AT_objc_ownership_cfretain;
break;
}
case 24:
if (!memcmp(Str, "objc_ownership_cfrelease", 24))
return AT_objc_ownership_cfrelease;
break;
}
return UnknownAttribute;
}

View File

@ -1543,6 +1543,10 @@ static void HandleObjCOwnershipParmAttr(Decl *d, const AttributeList &Attr,
default:
assert(0 && "invalid ownership attribute");
return;
case AttributeList::AT_objc_ownership_release:
name = "objc_ownership_release"; break;
case AttributeList::AT_objc_ownership_cfrelease:
name = "objc_ownership_cfrelease"; break;
case AttributeList::AT_objc_ownership_retain:
name = "objc_ownership_retain"; break;
case AttributeList::AT_objc_ownership_cfretain:
@ -1558,6 +1562,10 @@ static void HandleObjCOwnershipParmAttr(Decl *d, const AttributeList &Attr,
default:
assert(0 && "invalid ownership attribute");
return;
case AttributeList::AT_objc_ownership_release:
d->addAttr(::new (S.Context) ObjCOwnershipReleaseAttr()); return;
case AttributeList::AT_objc_ownership_cfrelease:
d->addAttr(::new (S.Context) ObjCOwnershipCFReleaseAttr()); return;
case AttributeList::AT_objc_ownership_retain:
d->addAttr(::new (S.Context) ObjCOwnershipRetainAttr()); return;
case AttributeList::AT_objc_ownership_cfretain:
@ -1603,6 +1611,8 @@ static void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) {
case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break;
// Checker-specific.
case AttributeList::AT_objc_ownership_release:
case AttributeList::AT_objc_ownership_cfrelease:
case AttributeList::AT_objc_ownership_retain:
case AttributeList::AT_objc_ownership_cfretain:
HandleObjCOwnershipParmAttr(D, Attr, S); break;

View File

@ -132,6 +132,8 @@ void f3() {
- (NSString*) returnsAnOwnedString __attribute__((objc_ownership_returns));
- (void) myRetain:(id)__attribute__((objc_ownership_retain))obj;
- (void) myCFRetain:(id)__attribute__((objc_ownership_cfretain))obj;
- (void) myRelease:(id)__attribute__((objc_ownership_release))obj;
- (void) myCFRelease:(id)__attribute__((objc_ownership_cfrelease))obj;
@end
void test_attr_1(TestOwnershipAttr *X) {
@ -149,3 +151,15 @@ void test_attr_3(TestOwnershipAttr *X) {
[X myCFRetain:str];
[str release];
}
void test_attr_4(TestOwnershipAttr *X) {
NSString *str = [X returnsAnOwnedString]; // no-warning
[X myRetain:str];
[X myRelease:str];
}
void test_attr_5(TestOwnershipAttr *X) {
NSString *str = [X returnsAnOwnedString]; // no-warning
[X myCFRetain:str];
[X myCFRelease:str];
}

View File

@ -413,6 +413,8 @@ void rdar6704930(unsigned char *s, unsigned int length) {
- (NSString*) returnsAnOwnedString __attribute__((objc_ownership_returns));
- (void) myRetain:(id)__attribute__((objc_ownership_retain))obj;
- (void) myCFRetain:(id)__attribute__((objc_ownership_cfretain))obj;
- (void) myRelease:(id)__attribute__((objc_ownership_release))obj;
- (void) myCFRelease:(id)__attribute__((objc_ownership_cfrelease))obj;
@end
void test_attr_1(TestOwnershipAttr *X) {
@ -431,3 +433,15 @@ void test_attr_3(TestOwnershipAttr *X) {
[str release];
}
void test_attr_4(TestOwnershipAttr *X) {
NSString *str = [X returnsAnOwnedString]; // expected-warning{{leak}}
[X myRetain:str];
[X myRelease:str];
}
void test_attr_5(TestOwnershipAttr *X) {
NSString *str = [X returnsAnOwnedString]; // expected-warning{{leak}}
[X myCFRetain:str];
[X myCFRelease:str];
}