blob: 596858f83a3e267582a2eb27591147929919ed9f [file] [log] [blame]
John McCalld1e40d52011-10-02 01:16:38 +00001// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -fblocks -verify %s
John McCallf85e1932011-06-15 23:02:42 +00002
3@interface Test0
4- (void) setBlock: (void(^)(void)) block;
5- (void) addBlock: (void(^)(void)) block;
6- (void) actNow;
7@end
8void test0(Test0 *x) {
9 [x setBlock: // expected-note {{block will be retained by the captured object}}
10 ^{ [x actNow]; }]; // expected-warning {{capturing 'x' strongly in this block is likely to lead to a retain cycle}}
11 x.block = // expected-note {{block will be retained by the captured object}}
12 ^{ [x actNow]; }; // expected-warning {{capturing 'x' strongly in this block is likely to lead to a retain cycle}}
13
14 [x addBlock: // expected-note {{block will be retained by the captured object}}
15 ^{ [x actNow]; }]; // expected-warning {{capturing 'x' strongly in this block is likely to lead to a retain cycle}}
16
17 // These actually don't cause retain cycles.
18 __weak Test0 *weakx = x;
19 [x addBlock: ^{ [weakx actNow]; }];
20 [x setBlock: ^{ [weakx actNow]; }];
21 x.block = ^{ [weakx actNow]; };
22
23 // These do cause retain cycles, but we're not clever enough to figure that out.
24 [weakx addBlock: ^{ [x actNow]; }];
25 [weakx setBlock: ^{ [x actNow]; }];
26 weakx.block = ^{ [x actNow]; };
27}
28
29@interface BlockOwner
Fariborz Jahanian528a4992011-09-14 18:03:46 +000030@property (retain) void (^strong)(void); // expected-warning {{retain'ed block property does not copy the block - use copy attribute instead}}
John McCallf85e1932011-06-15 23:02:42 +000031@end
32
33@interface Test1 {
34@public
35 BlockOwner *owner;
36};
37@property (retain) BlockOwner *owner;
38@property (assign) __strong BlockOwner *owner2; // expected-error {{unsafe_unretained property 'owner2' may not also be declared __strong}}
39@property (assign) BlockOwner *owner3;
40@end
41void test1(Test1 *x) {
42 x->owner.strong = ^{ (void) x; }; // expected-warning {{retain cycle}} expected-note {{block will be retained by an object strongly retained by the captured object}}
43 x.owner.strong = ^{ (void) x; }; // expected-warning {{retain cycle}} expected-note {{block will be retained by an object strongly retained by the captured object}}
44 x.owner2.strong = ^{ (void) x; };
45 x.owner3.strong = ^{ (void) x; };
46}
47
48@implementation Test1 {
49 BlockOwner * __unsafe_unretained owner3ivar;
50 __weak BlockOwner *weakowner;
51}
52@dynamic owner;
53@dynamic owner2;
54@synthesize owner3 = owner3ivar;
55
56- (id) init {
57 self.owner.strong = ^{ (void) owner; }; // expected-warning {{retain cycle}} expected-note {{block will be retained by an object strongly retained by the captured object}}
58 self.owner2.strong = ^{ (void) owner; };
59
60 // TODO: should we warn here? What's the story with this kind of mismatch?
61 self.owner3.strong = ^{ (void) owner; };
62
63 owner.strong = ^{ (void) owner; }; // expected-warning {{retain cycle}} expected-note {{block will be retained by an object strongly retained by the captured object}}
64
65 owner.strong = ^{ ^{ (void) owner; }(); }; // expected-warning {{retain cycle}} expected-note {{block will be retained by an object strongly retained by the captured object}}
66
67 owner.strong = ^{ (void) sizeof(self); // expected-note {{block will be retained by an object strongly retained by the captured object}}
68 (void) owner; }; // expected-warning {{capturing 'self' strongly in this block is likely to lead to a retain cycle}}
69
70 weakowner.strong = ^{ (void) owner; };
71
72 return self;
73}
74- (void) foo {
75 owner.strong = ^{ (void) owner; }; // expected-warning {{retain cycle}} expected-note {{block will be retained by an object strongly retained by the captured object}}
76}
77@end
78
79void test2_helper(id);
80@interface Test2 {
81 void (^block)(void);
82 id x;
83}
84@end
85@implementation Test2
86- (void) test {
87 block = ^{ // expected-note {{block will be retained by an object strongly retained by the captured object}}
88 test2_helper(x); // expected-warning {{capturing 'self' strongly in this block is likely to lead to a retain cycle}}
89 };
90}
91@end