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