Home | History | Annotate | Download | only in SemaObjC
      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