From: Ted Kremenek Date: Mon, 27 Apr 2009 19:36:56 +0000 (+0000) Subject: Add two new checker-specific attributes: 'objc_ownership_release' and X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c6a59e4bf225c7f8152faca72897321f0f6cabd1;p=clang 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70235 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h index bde0c9b705..91abcffdcd 100644 --- a/include/clang/AST/Attr.h +++ b/include/clang/AST/Attr.h @@ -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) diff --git a/include/clang/Parse/AttributeList.h b/include/clang/Parse/AttributeList.h index 616d293fd6..4de27c1d99 100644 --- a/include/clang/Parse/AttributeList.h +++ b/include/clang/Parse/AttributeList.h @@ -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, diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp index 8f07b2c9f4..538f4f2722 100644 --- a/lib/Analysis/CFRefCount.cpp +++ b/lib/Analysis/CFRefCount.cpp @@ -1112,7 +1112,15 @@ RetainSummaryManager::getMethodSummaryFromAnnotations(ObjCMethodDecl *MD) { else if ((*I)->getAttr()) { ScratchArgs.push_back(std::make_pair(i, IncRef)); hasArgEffect = true; - } + } + else if ((*I)->getAttr()) { + ScratchArgs.push_back(std::make_pair(i, DecRefMsg)); + hasArgEffect = true; + } + else if ((*I)->getAttr()) { + ScratchArgs.push_back(std::make_pair(i, DecRef)); + hasArgEffect = true; + } } if (!hasRetEffect && !hasArgEffect) diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp index 50cc031225..2df87bfe1c 100644 --- a/lib/Frontend/PCHReaderDecl.cpp +++ b/lib/Frontend/PCHReaderDecl.cpp @@ -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); diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp index bb85b68b7e..8ff688e6e3 100644 --- a/lib/Frontend/PCHWriter.cpp +++ b/lib/Frontend/PCHWriter.cpp @@ -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: diff --git a/lib/Parse/AttributeList.cpp b/lib/Parse/AttributeList.cpp index 9e46159153..cbc0031428 100644 --- a/lib/Parse/AttributeList.cpp +++ b/lib/Parse/AttributeList.cpp @@ -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; } diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index cf722e511d..c72b7ad7e8 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -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; diff --git a/test/Analysis/retain-release-gc-only.m b/test/Analysis/retain-release-gc-only.m index 89be76085b..91f3541ce4 100644 --- a/test/Analysis/retain-release-gc-only.m +++ b/test/Analysis/retain-release-gc-only.m @@ -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]; +} diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m index b547aa0373..ef10ce32b6 100644 --- a/test/Analysis/retain-release.m +++ b/test/Analysis/retain-release.m @@ -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]; +} +