blob: 728ffcb951d72328fb3ef0793a282d9620ec2ca2 [file] [log] [blame]
Jordan Rosed3934582012-09-28 22:21:30 +00001// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -fblocks -Wno-objc-root-class -Warc-repeated-use-of-weak -verify %s
2
3@interface Test {
4@public
5 Test *ivar;
6}
7@property(weak) Test *weakProp;
8@property(strong) Test *strongProp;
9
10- (__weak id)implicitProp;
11
12+ (__weak id)weakProp;
13@end
14
15extern void use(id);
16extern id get();
17extern bool condition();
18#define nil ((id)0)
19
20void sanity(Test *a) {
21 use(a.weakProp); // expected-warning{{weak property is accessed multiple times in this function but may be unpredictably set to nil; assign to a strong variable to keep the object alive}}
22 use(a.weakProp); // expected-note{{also accessed here}}
23
24 use(a.strongProp);
25 use(a.strongProp); // no-warning
26
27 use(a.weakProp); // expected-note{{also accessed here}}
28}
29
30void singleUse(Test *a) {
31 use(a.weakProp); // no-warning
32 use(a.strongProp); // no-warning
33}
34
35void assignsOnly(Test *a) {
36 a.weakProp = get(); // no-warning
37
38 id next = get();
39 if (next)
40 a.weakProp = next; // no-warning
41}
42
43void assignThenRead(Test *a) {
44 a.weakProp = get(); // expected-note{{also accessed here}}
45 use(a.weakProp); // expected-warning{{weak property is accessed multiple times}}
46}
47
48void twoVariables(Test *a, Test *b) {
49 use(a.weakProp); // no-warning
50 use(b.weakProp); // no-warning
51}
52
53void doubleLevelAccess(Test *a) {
54 use(a.strongProp.weakProp); // expected-warning{{weak property may be accessed multiple times in this function but may be unpredictably set to nil; assign to a strong variable to keep the object alive}}
55 use(a.strongProp.weakProp); // expected-note{{also accessed here}}
56}
57
58void doubleLevelAccessIvar(Test *a) {
59 use(a.strongProp.weakProp); // expected-warning{{weak property may be accessed multiple times}}
60 use(a.strongProp.weakProp); // expected-note{{also accessed here}}
61}
62
63void implicitProperties(Test *a) {
64 use(a.implicitProp); // expected-warning{{weak property is accessed multiple times}}
65 use(a.implicitProp); // expected-note{{also accessed here}}
66}
67
68void classProperties() {
69 use(Test.weakProp); // expected-warning{{weak property is accessed multiple times}}
70 use(Test.weakProp); // expected-note{{also accessed here}}
71}
72
73void classPropertiesAreDifferent(Test *a) {
74 use(Test.weakProp); // no-warning
75 use(a.weakProp); // no-warning
76 use(a.strongProp.weakProp); // no-warning
77}
78
79
80void assignToStrongWrongInit(Test *a) {
81 id val = a.weakProp; // expected-note{{also accessed here}}
82 use(a.weakProp); // expected-warning{{weak property is accessed multiple times}}
83}
84
85void assignToStrongWrong(Test *a) {
86 id val;
87 val = a.weakProp; // expected-note{{also accessed here}}
88 use(a.weakProp); // expected-warning{{weak property is accessed multiple times}}
89}
90
91void assignToStrongOK(Test *a) {
92 if (condition()) {
93 id val = a.weakProp; // no-warning
94 (void)val;
95 } else {
96 id val;
97 val = a.weakProp; // no-warning
98 (void)val;
99 }
100}
101
102void assignToStrongConditional(Test *a) {
103 id val = (condition() ? a.weakProp : a.weakProp); // no-warning
104 id val2 = a.implicitProp ?: a.implicitProp; // no-warning
105}
106
107void testBlock(Test *a) {
108 use(a.weakProp); // no-warning
109
110 use(^{
111 use(a.weakProp); // expected-warning{{weak property is accessed multiple times in this block}}
112 use(a.weakProp); // expected-note{{also accessed here}}
113 });
114}
115
116
117@interface Test (Methods)
118@end
119
120@implementation Test (Methods)
121- (void)sanity {
122 use(self.weakProp); // expected-warning{{weak property is accessed multiple times in this method but may be unpredictably set to nil; assign to a strong variable to keep the object alive}}
123 use(self.weakProp); // expected-note{{also accessed here}}
124}
125
126- (void)doubleLevelAccessForSelf {
127 use(self.strongProp.weakProp); // expected-warning{{weak property is accessed multiple times}}
128 use(self.strongProp.weakProp); // expected-note{{also accessed here}}
129
130 use(self->ivar.weakProp); // expected-warning{{weak property is accessed multiple times}}
131 use(self->ivar.weakProp); // expected-note{{also accessed here}}
132}
133
134- (void)distinctFromOther:(Test *)other {
135 use(self.strongProp.weakProp); // no-warning
136 use(other.strongProp.weakProp); // no-warning
137
138 use(self->ivar.weakProp); // no-warning
139 use(other->ivar.weakProp); // no-warning
140}
141@end
142
143
144class Wrapper {
145 Test *a;
146
147public:
148 void fields() {
149 use(a.weakProp); // expected-warning{{weak property is accessed multiple times in this function but may be unpredictably set to nil; assign to a strong variable to keep the object alive}}
150 use(a.weakProp); // expected-note{{also accessed here}}
151 }
152
153 void distinctFromOther(Test *b, const Wrapper &w) {
154 use(a.weakProp); // no-warning
155 use(b.weakProp); // no-warning
156 use(w.a.weakProp); // no-warning
157 }
158
159 static void doubleLevelAccessField(const Wrapper &x, const Wrapper &y) {
160 use(x.a.weakProp); // expected-warning{{weak property may be accessed multiple times}}
161 use(y.a.weakProp); // expected-note{{also accessed here}}
162 }
163};
164
165
166// -----------------------
167// False positives
168// -----------------------
169
170// Most of these would require flow-sensitive analysis to silence correctly.
171
172void assignAfterRead(Test *a) {
173 if (!a.weakProp) // expected-warning{{weak property is accessed multiple times}}
174 a.weakProp = get(); // expected-note{{also accessed here}}
175}
176
177void assignNil(Test *a) {
178 if (condition())
179 a.weakProp = nil; // expected-note{{also accessed here}}
180
181 use(a.weakProp); // expected-warning{{weak property is accessed multiple times}}
182}
183
184void branch(Test *a) {
185 if (condition())
186 use(a.weakProp); // expected-warning{{weak property is accessed multiple times}}
187 else
188 use(a.weakProp); // expected-note{{also accessed here}}
189}
190
191void doubleLevelAccess(Test *a, Test *b) {
192 use(a.strongProp.weakProp); // expected-warning{{weak property may be accessed multiple times}}
193 use(b.strongProp.weakProp); // expected-note{{also accessed here}}
194
195 use(a.weakProp.weakProp); // no-warning
196}
197
198void doubleLevelAccessIvar(Test *a, Test *b) {
199 use(a->ivar.weakProp); // expected-warning{{weak property may be accessed multiple times}}
200 use(b->ivar.weakProp); // expected-note{{also accessed here}}
201
202 use(a.strongProp.weakProp); // no-warning
203}