diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 24912b846f..e516be526c 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -408,7 +408,7 @@ def warn_attribute_weak_import_invalid_on_definition : Warning< "'weak_import' attribute cannot be specified on a definition">; def warn_attribute_wrong_decl_type : Warning< "'%0' attribute only applies to %select{function|union|" - "variable and function|function or method|parameter}1 types">; + "variable and function|function or method|parameter|parameter or Objective-C method}1 types">; def warn_gnu_inline_attribute_requires_inline : Warning< "'gnu_inline' attribute requires function to be marked 'inline'," " attribute ignored">; diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 4853028ba3..1e3a7e58bb 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -1559,10 +1559,10 @@ static void HandleObjCOwnershipReturnsAttr(Decl *d, const AttributeList &Attr, d->addAttr(::new (S.Context) ObjCOwnershipReturnsAttr()); } -static void HandleObjCOwnershipParmAttr(Decl *d, const AttributeList &Attr, - Sema &S) { +static void HandleObjCOwnershipAttr(Decl *d, const AttributeList &Attr, + Sema &S, bool attachToMethodDecl = false) { - if (!isa(d)) { + if (!isa(d) && (!attachToMethodDecl || !isa(d))){ const char *name; switch (Attr.getKind()) { @@ -1582,7 +1582,8 @@ static void HandleObjCOwnershipParmAttr(Decl *d, const AttributeList &Attr, }; S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) << name - << 4 /* parameter */; + << (attachToMethodDecl ? 5 /* parameter or method decl */ + : 4 /* parameter */); return; } @@ -1643,10 +1644,11 @@ static void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) { // Checker-specific. case AttributeList::AT_objc_ownership_cfrelease: case AttributeList::AT_objc_ownership_cfretain: + HandleObjCOwnershipAttr(D, Attr, S); break; case AttributeList::AT_objc_ownership_make_collectable: case AttributeList::AT_objc_ownership_release: case AttributeList::AT_objc_ownership_retain: - HandleObjCOwnershipParmAttr(D, Attr, S); break; + HandleObjCOwnershipAttr(D, Attr, S, true); break; case AttributeList::AT_objc_ownership_returns: HandleObjCOwnershipReturnsAttr(D, Attr, S); break; diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m index 8add2bb753..d36f985e3a 100644 --- a/test/Analysis/retain-release.m +++ b/test/Analysis/retain-release.m @@ -440,6 +440,9 @@ void rdar6704930(unsigned char *s, unsigned int length) { - (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) myRetain __attribute__((objc_ownership_retain)); +- (void) myRelease __attribute__((objc_ownership_release)); @end @interface TestAttrHelper : NSObject