From: Fariborz Jahanian Date: Wed, 14 Sep 2011 18:03:46 +0000 (+0000) Subject: objc-arc: warn when a 'retain' block property is X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=528a499eb84d61667f65b16a13780c135b822f6b;p=clang objc-arc: warn when a 'retain' block property is declared which does not force a 'copy' of the block literal object. // rdar://9829425 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@139706 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 186908252f..bb24f21e24 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -494,6 +494,9 @@ def warn_property_attr_mismatch : Warning< def warn_objc_property_copy_missing_on_block : Warning< "'copy' attribute must be specified for the block property " "when -fobjc-gc-only is specified">; +def warn_objc_property_retain_of_block : Warning< + "retain'ed block property does not copy the block " + "- use copy attribute instead">; def warn_atomic_property_rule : Warning< "writable atomic property %0 cannot pair a synthesized setter/getter " "with a user defined setter/getter">; diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp index fb0d13a66a..33c5e71b5e 100644 --- a/lib/Sema/SemaObjCProperty.cpp +++ b/lib/Sema/SemaObjCProperty.cpp @@ -1701,7 +1701,7 @@ void Sema::CheckObjCPropertyAttributes(Decl *PDecl, (Attributes & ObjCDeclSpec::DQ_PR_weak)) { Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) << "retain" << "weak"; - Attributes &= ~ObjCDeclSpec::DQ_PR_weak; + Attributes &= ~ObjCDeclSpec::DQ_PR_retain; } else if ((Attributes & ObjCDeclSpec::DQ_PR_strong) && (Attributes & ObjCDeclSpec::DQ_PR_weak)) { @@ -1743,4 +1743,10 @@ void Sema::CheckObjCPropertyAttributes(Decl *PDecl, && getLangOptions().getGC() == LangOptions::GCOnly && PropertyTy->isBlockPointerType()) Diag(Loc, diag::warn_objc_property_copy_missing_on_block); + else if (getLangOptions().ObjCAutoRefCount && + (Attributes & ObjCDeclSpec::DQ_PR_retain) && + !(Attributes & ObjCDeclSpec::DQ_PR_readonly) && + !(Attributes & ObjCDeclSpec::DQ_PR_strong) && + PropertyTy->isBlockPointerType()) + Diag(Loc, diag::warn_objc_property_retain_of_block); } diff --git a/test/SemaObjC/arc-retain-block-property.m b/test/SemaObjC/arc-retain-block-property.m new file mode 100644 index 0000000000..a1b181c4f7 --- /dev/null +++ b/test/SemaObjC/arc-retain-block-property.m @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -fsyntax-only -fblocks -fobjc-arc -fobjc-nonfragile-abi -verify %s +// rdar://9829425 + +extern void doSomething(); + +@interface Test +{ +@public + void (^aBlock)(void); +} +@property (retain) void (^aBlock)(void); // expected-warning {{retain'ed block property does not copy the block - use copy attribute instead}} +@property (weak, retain) void (^aBlockW)(void); // expected-error {{property attributes 'retain' and 'weak' are mutually exclusive}} +@property (strong, retain) void (^aBlockS)(void); // OK +@property (readonly, retain) void (^aBlockR)(void); // OK +@property (copy, retain) void (^aBlockC)(void); // expected-error {{property attributes 'copy' and 'retain' are mutually exclusive}} +@property (assign, retain) void (^aBlockA)(void); // expected-error {{property attributes 'assign' and 'retain' are mutually exclusive}} +@end + +@implementation Test +@synthesize aBlock; +@dynamic aBlockW, aBlockS, aBlockR, aBlockC, aBlockA; +@end + +int main() { + Test *t; + t.aBlock = ^{ doSomething(); }; + t.aBlockW = ^{ doSomething(); }; + t.aBlockS = ^{ doSomething(); }; +} + diff --git a/test/SemaObjC/warn-retain-cycle.m b/test/SemaObjC/warn-retain-cycle.m index 71385b8400..8530195756 100644 --- a/test/SemaObjC/warn-retain-cycle.m +++ b/test/SemaObjC/warn-retain-cycle.m @@ -27,7 +27,7 @@ void test0(Test0 *x) { } @interface BlockOwner -@property (retain) void (^strong)(void); +@property (retain) void (^strong)(void); // expected-warning {{retain'ed block property does not copy the block - use copy attribute instead}} @end @interface Test1 {