summaryrefslogtreecommitdiffstats
path: root/test/SemaObjC/weak-receiver-warn.m
blob: 88b867ed0d04722b2c0da44f41d233417e2397d9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -fblocks -Wno-objc-root-class -Wreceiver-is-weak -verify %s
// rdar://10225276

@interface Test0
- (void) setBlock: (void(^)(void)) block;
- (void) addBlock: (void(^)(void)) block;
- (void) actNow;
@end

void test0(Test0 *x) {
  __weak Test0 *weakx = x;
  [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}}
  [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}}
  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}}

  [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}}
  [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}}
  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}}
}

@interface Test
{
  __weak Test* weak_prop;
}
- (void) Meth;
@property  __weak Test* weak_prop; // expected-note {{property declared here}}
@property (weak, atomic) id weak_atomic_prop; // expected-note {{property declared here}}
- (__weak id) P; // expected-note {{method 'P' declared here}}
@end

@implementation Test
- (void) Meth {
    if (self.weak_prop) {
      self.weak_prop = 0;
    }
    if (self.weak_atomic_prop) {
      self.weak_atomic_prop = 0;
    }
    [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}}
    id pi = self.P;

    [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}}

    [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}}
}

- (__weak id) P { return 0; }
@dynamic weak_prop, weak_atomic_prop;
@end


@interface MyClass {
    __weak MyClass *_parent;
}
@property (weak) MyClass *parent; // expected-note 4 {{property declared here}}
@end

@implementation MyClass
@synthesize parent = _parent;

- (void)doSomething
{
    [[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}}

    (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}}
}

@end


// Weak properties on protocols can be synthesized by an adopting class.
@protocol MyProtocol
@property (weak) id object; // expected-note 2 {{property declared here}}
@end

void testProtocol(id <MyProtocol> input) {
  [[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}}
  [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}}
}


@interface Subclass : MyClass
// Unnecessarily redeclare -parent.
- (id)parent;
@end

@implementation Subclass

- (id)parent {
  return [super parent];
}

- (void)doSomethingElse {
  [[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}}

  (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}}
}

@end