1 // RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -fblocks -Wno-objc-root-class -Wreceiver-is-weak -verify %s 2 // rdar://10225276 3 4 @interface Test0 5 - (void) setBlock: (void(^)(void)) block; 6 - (void) addBlock: (void(^)(void)) block; 7 - (void) actNow; 8 @end 9 10 void test0(Test0 *x) { 11 __weak Test0 *weakx = x; 12 [x addBlock: ^{ [weakx actNow]; }]; // expected-warning {{weak receiver may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}} 13 [x setBlock: ^{ [weakx actNow]; }]; // expected-warning {{weak receiver may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}} 14 x.block = ^{ [weakx actNow]; }; // expected-warning {{weak receiver may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}} 15 16 [weakx addBlock: ^{ [x actNow]; }]; // expected-warning {{weak receiver may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}} 17 [weakx setBlock: ^{ [x actNow]; }]; // expected-warning {{weak receiver may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}} 18 weakx.block = ^{ [x actNow]; }; // expected-warning {{weak receiver may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}} 19 } 20 21 @interface Test 22 { 23 __weak Test* weak_prop; 24 } 25 - (void) Meth; 26 @property __weak Test* weak_prop; // expected-note {{property declared here}} 27 @property (weak, atomic) id weak_atomic_prop; // expected-note {{property declared here}} 28 - (__weak id) P; // expected-note {{method 'P' declared here}} 29 @end 30 31 @implementation Test 32 - (void) Meth { 33 if (self.weak_prop) { 34 self.weak_prop = 0; 35 } 36 if (self.weak_atomic_prop) { 37 self.weak_atomic_prop = 0; 38 } 39 [self.weak_prop Meth]; // expected-warning {{weak property may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}} 40 id pi = self.P; 41 42 [self.weak_atomic_prop Meth]; // expected-warning {{weak property may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}} 43 44 [self.P Meth]; // expected-warning {{weak implicit property may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}} 45 } 46 47 - (__weak id) P { return 0; } 48 @dynamic weak_prop, weak_atomic_prop; 49 @end 50 51 52 @interface MyClass { 53 __weak MyClass *_parent; 54 } 55 @property (weak) MyClass *parent; // expected-note 4 {{property declared here}} 56 @end 57 58 @implementation MyClass 59 @synthesize parent = _parent; 60 61 - (void)doSomething 62 { 63 [[self parent] doSomething]; // expected-warning {{weak property may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}} 64 65 (void)self.parent.doSomething; // expected-warning {{weak property may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}} 66 } 67 68 @end 69 70 71 // Weak properties on protocols can be synthesized by an adopting class. 72 @protocol MyProtocol 73 @property (weak) id object; // expected-note 2 {{property declared here}} 74 @end 75 76 void testProtocol(id <MyProtocol> input) { 77 [[input object] Meth]; // expected-warning {{weak property may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}} 78 [input.object Meth]; // expected-warning {{weak property may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}} 79 } 80 81 82 @interface Subclass : MyClass 83 // Unnecessarily redeclare -parent. 84 - (id)parent; 85 @end 86 87 @implementation Subclass 88 89 - (id)parent { 90 return [super parent]; 91 } 92 93 - (void)doSomethingElse { 94 [[self parent] doSomething]; // expected-warning {{weak property may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}} 95 96 (void)self.parent.doSomething; // expected-warning {{weak property may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}} 97 } 98 99 @end 100 101