forked from OSchip/llvm-project
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:
parent
bfa037705e
commit
84bfa2c2dc
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue