diff options
-rw-r--r-- | include/clang/AST/Attr.h | 12 | ||||
-rw-r--r-- | include/clang/Parse/AttributeList.h | 11 | ||||
-rw-r--r-- | lib/Analysis/CFRefCount.cpp | 4 | ||||
-rw-r--r-- | lib/Frontend/PCHReaderDecl.cpp | 3 | ||||
-rw-r--r-- | lib/Frontend/PCHWriter.cpp | 3 | ||||
-rw-r--r-- | lib/Parse/AttributeList.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/SemaDeclAttr.cpp | 25 | ||||
-rw-r--r-- | test/Analysis/retain-release-gc-only.m | 12 |
8 files changed, 52 insertions, 22 deletions
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h index badab47911..b850958f1e 100644 --- a/include/clang/AST/Attr.h +++ b/include/clang/AST/Attr.h @@ -59,11 +59,12 @@ public: NonNull, ObjCException, ObjCNSObject, - ObjCOwnershipCFRelease, // Clang/Checker-specific. - ObjCOwnershipCFRetain, // Clang/Checker-specific. - ObjCOwnershipRelease, // Clang/Checker-specific. - ObjCOwnershipRetain, // Clang/Checker-specific. - ObjCOwnershipReturns, // Clang/Checker-specific. + ObjCOwnershipCFRelease, // Clang/Checker-specific. + ObjCOwnershipCFRetain, // Clang/Checker-specific. + ObjCOwnershipMakeCollectable, // Clang/Checker-specific. + ObjCOwnershipRelease, // Clang/Checker-specific. + ObjCOwnershipRetain, // Clang/Checker-specific. + ObjCOwnershipReturns, // Clang/Checker-specific. Overloadable, // Clang-specific Packed, Pure, @@ -467,6 +468,7 @@ DEF_SIMPLE_ATTR(ObjCOwnershipCFRelease); DEF_SIMPLE_ATTR(ObjCOwnershipRelease); DEF_SIMPLE_ATTR(ObjCOwnershipCFRetain); DEF_SIMPLE_ATTR(ObjCOwnershipRetain); +DEF_SIMPLE_ATTR(ObjCOwnershipMakeCollectable); DEF_SIMPLE_ATTR(ObjCOwnershipReturns); #undef DEF_SIMPLE_ATTR diff --git a/include/clang/Parse/AttributeList.h b/include/clang/Parse/AttributeList.h index 4de27c1d99..1528043196 100644 --- a/include/clang/Parse/AttributeList.h +++ b/include/clang/Parse/AttributeList.h @@ -76,11 +76,12 @@ public: AT_nothrow, AT_nsobject, AT_objc_exception, - 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_ownership_cfrelease, // Clang-specific. + AT_objc_ownership_cfretain, // Clang-specific. + AT_objc_ownership_make_collectable, // 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 538f4f2722..e1483d692d 100644 --- a/lib/Analysis/CFRefCount.cpp +++ b/lib/Analysis/CFRefCount.cpp @@ -1121,6 +1121,10 @@ RetainSummaryManager::getMethodSummaryFromAnnotations(ObjCMethodDecl *MD) { ScratchArgs.push_back(std::make_pair(i, DecRef)); hasArgEffect = true; } + else if ((*I)->getAttr<ObjCOwnershipMakeCollectableAttr>()) { + ScratchArgs.push_back(std::make_pair(i, MakeCollectable)); + hasArgEffect = true; + } } if (!hasRetEffect && !hasArgEffect) diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp index fc14a2623c..22699e5716 100644 --- a/lib/Frontend/PCHReaderDecl.cpp +++ b/lib/Frontend/PCHReaderDecl.cpp @@ -476,8 +476,9 @@ Attr *PCHReader::ReadAttributes() { SIMPLE_ATTR(ObjCException); SIMPLE_ATTR(ObjCNSObject); SIMPLE_ATTR(ObjCOwnershipCFRelease); - SIMPLE_ATTR(ObjCOwnershipRelease); SIMPLE_ATTR(ObjCOwnershipCFRetain); + SIMPLE_ATTR(ObjCOwnershipMakeCollectable); + SIMPLE_ATTR(ObjCOwnershipRelease); SIMPLE_ATTR(ObjCOwnershipRetain); SIMPLE_ATTR(ObjCOwnershipReturns); SIMPLE_ATTR(Overloadable); diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp index 04b552a488..8374e092a5 100644 --- a/lib/Frontend/PCHWriter.cpp +++ b/lib/Frontend/PCHWriter.cpp @@ -1545,8 +1545,9 @@ void PCHWriter::WriteAttributeRecord(const Attr *Attr) { case Attr::ObjCException: case Attr::ObjCNSObject: case Attr::ObjCOwnershipCFRelease: - case Attr::ObjCOwnershipRelease: case Attr::ObjCOwnershipCFRetain: + case Attr::ObjCOwnershipMakeCollectable: + case Attr::ObjCOwnershipRelease: case Attr::ObjCOwnershipRetain: case Attr::ObjCOwnershipReturns: case Attr::Overloadable: diff --git a/lib/Parse/AttributeList.cpp b/lib/Parse/AttributeList.cpp index cbc0031428..cbd230cc51 100644 --- a/lib/Parse/AttributeList.cpp +++ b/lib/Parse/AttributeList.cpp @@ -152,6 +152,10 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) { case 24: if (!memcmp(Str, "objc_ownership_cfrelease", 24)) return AT_objc_ownership_cfrelease; + break; + case 31: + if (!memcmp(Str, "objc_ownership_make_collectable", 31)) + return AT_objc_ownership_make_collectable; break; } return UnknownAttribute; diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 09c627e42d..9e550ba44f 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -1539,14 +1539,16 @@ static void HandleObjCOwnershipParmAttr(Decl *d, const AttributeList &Attr, default: assert(0 && "invalid ownership attribute"); return; + case AttributeList::AT_objc_ownership_cfrelease: + name = "objc_ownership_cfrelease"; break; + case AttributeList::AT_objc_ownership_cfretain: + name = "objc_ownership_cfretain"; break; + case AttributeList::AT_objc_ownership_make_collectable: + name = "objc_ownership_make_collectable"; break; 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: - name = "objc_ownership_cfretain"; break; }; S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) << name @@ -1558,14 +1560,16 @@ 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: d->addAttr(::new (S.Context) ObjCOwnershipCFRetainAttr()); return; + case AttributeList::AT_objc_ownership_make_collectable: + d->addAttr(::new (S.Context) ObjCOwnershipMakeCollectableAttr()); return; + case AttributeList::AT_objc_ownership_release: + d->addAttr(::new (S.Context) ObjCOwnershipReleaseAttr()); return; + case AttributeList::AT_objc_ownership_retain: + d->addAttr(::new (S.Context) ObjCOwnershipRetainAttr()); return; } } @@ -1607,10 +1611,11 @@ 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_cfrelease: + case AttributeList::AT_objc_ownership_cfretain: + case AttributeList::AT_objc_ownership_make_collectable: 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; case AttributeList::AT_objc_ownership_returns: HandleObjCOwnershipReturnsAttr(D, Attr, S); break; diff --git a/test/Analysis/retain-release-gc-only.m b/test/Analysis/retain-release-gc-only.m index d4871f4de1..e008f4a795 100644 --- a/test/Analysis/retain-release-gc-only.m +++ b/test/Analysis/retain-release-gc-only.m @@ -134,6 +134,7 @@ void f3() { - (void) myCFRetain:(id)__attribute__((objc_ownership_cfretain))obj; - (void) myRelease:(id)__attribute__((objc_ownership_release))obj; - (void) myCFRelease:(id)__attribute__((objc_ownership_cfrelease))obj; +- (void) makeCollectable:(id)__attribute__((objc_ownership_make_collectable))obj; @end void test_attr_1(TestOwnershipAttr *X) { @@ -181,3 +182,14 @@ void test_attr_5c(TestOwnershipAttr *X) { [X myCFRetain:str]; [X myCFRelease:str]; } + +void test_attr_6a(TestOwnershipAttr *X) { + CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{leak}} +} + +void test_attr_6b(TestOwnershipAttr *X) { + CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning + [X makeCollectable:(id)A]; +} + + |