Index: include/clang/Basic/Attr.td =================================================================== --- include/clang/Basic/Attr.td +++ include/clang/Basic/Attr.td @@ -531,6 +531,15 @@ let Documentation = [Undocumented]; } +// cf_no_release indicates that the call graph reachable from the given function +// does not decrement reference counts in a manner that is visible to the +// compiler. +def CFNoRelease : InheritableAttr { + let Spellings = [GNU<"cf_no_release">]; + let Subjects = SubjectList<[Function]>; + let Documentation = [Undocumented]; +} + def Cleanup : InheritableAttr { let Spellings = [GCC<"cleanup">]; let Args = [FunctionArgument<"FunctionDecl">]; Index: lib/Sema/SemaDeclAttr.cpp =================================================================== --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -5279,7 +5279,9 @@ case AttributeList::AT_NSConsumesSelf: handleSimpleAttribute(S, D, Attr); break; - + case AttributeList::AT_CFNoRelease: + handleSimpleAttribute(S, D, Attr); + break; case AttributeList::AT_NSReturnsAutoreleased: case AttributeList::AT_NSReturnsNotRetained: case AttributeList::AT_CFReturnsNotRetained: Index: test/SemaObjC/attr-cf_no_release.m =================================================================== --- /dev/null +++ test/SemaObjC/attr-cf_no_release.m @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -fobjc-arc -verify -fsyntax-only %s +// Make sure we accept the cf_no_release attribute in all of the appropriate places. + +#define CF_NO_RELEASE __attribute__((cf_no_release)) + +int x CF_NO_RELEASE; // expected-warning{{'cf_no_release' attribute only applies to functions}} + +typedef struct __CFFoo *CFFooRef; + +int valid1() CF_NO_RELEASE; +void valid2() CF_NO_RELEASE; +CFFooRef valid3() CF_NO_RELEASE; +id valid4() CF_NO_RELEASE; + +@interface Test +- (int)invalid1 CF_NO_RELEASE; // expected-warning{{'cf_no_release' attribute only applies to functions}} +- (void)invalid2 CF_NO_RELEASE; // expected-warning{{'cf_no_release' attribute only applies to functions}} +- (CFFooRef)invalid3 CF_NO_RELEASE; // expected-warning{{'cf_no_release' attribute only applies to functions}} +- (id)invalid4 CF_NO_RELEASE; // expected-warning{{'cf_no_release' attribute only applies to functions}} + +@property int invalidProp1 CF_NO_RELEASE; // expected-warning{{'cf_no_release' attribute only applies to functions}} +@property void invalidProp2 CF_NO_RELEASE; // expected-warning{{'cf_no_release' attribute only applies to functions}} +@property CFFooRef invalidProp3 CF_NO_RELEASE; // expected-warning{{'cf_no_release' attribute only applies to functions}} +@property id invalidProp4 CF_NO_RELEASE; // expected-warning{{'cf_no_release' attribute only applies to functions}} +@end + +void invalidParam(int a CF_NO_RELEASE, // expected-warning{{'cf_no_release' attribute only applies to functions}} + int *b CF_NO_RELEASE, // expected-warning{{'cf_no_release' attribute only applies to functions}} + id c CF_NO_RELEASE, // expected-warning{{'cf_no_release' attribute only applies to functions}} + void *d CF_NO_RELEASE, // expected-warning{{'cf_no_release' attribute only applies to functions}} + CFFooRef e CF_NO_RELEASE); // expected-warning{{'cf_no_release' attribute only applies to functions}}