objc-arc: warn when a 'retain' block property is

declared which does not force a 'copy' of the block literal
object. // rdar://9829425

llvm-svn: 139706
This commit is contained in:
Fariborz Jahanian 2011-09-14 18:03:46 +00:00
parent f915acc613
commit 1723e17b78
4 changed files with 41 additions and 2 deletions

View File

@ -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">;

View File

@ -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);
}

View File

@ -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(); };
}

View File

@ -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 {