1 // RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -fblocks -Wno-objc-root-class -std=c++11 -Warc-repeated-use-of-weak -verify %s
8 @property(weak) Test *weakProp;
9 @property(strong) Test *strongProp;
11 - (__weak id)implicitProp;
13 + (__weak id)weakProp;
18 extern bool condition();
21 void sanity(Test *a) {
22 use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times in this function but may be unpredictably set to nil; assign to a strong variable to keep the object alive}}
23 use(a.weakProp); // expected-note{{also accessed here}}
26 use(a.strongProp); // no-warning
28 use(a.weakProp); // expected-note{{also accessed here}}
31 void singleUse(Test *a) {
32 use(a.weakProp); // no-warning
33 use(a.strongProp); // no-warning
36 void assignsOnly(Test *a) {
37 a.weakProp = get(); // no-warning
41 a.weakProp = next; // no-warning
43 a->weakIvar = get(); // no-warning
46 a->weakIvar = next; // no-warning
49 x = get(); // no-warning
52 x = next; // no-warning
55 void assignThenRead(Test *a) {
56 a.weakProp = get(); // expected-note{{also accessed here}}
57 use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
60 void twoVariables(Test *a, Test *b) {
61 use(a.weakProp); // no-warning
62 use(b.weakProp); // no-warning
65 void doubleLevelAccess(Test *a) {
66 use(a.strongProp.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times in this function and may be unpredictably set to nil; assign to a strong variable to keep the object alive}}
67 use(a.strongProp.weakProp); // expected-note{{also accessed here}}
70 void doubleLevelAccessIvar(Test *a) {
71 use(a.strongProp.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}
72 use(a.strongProp.weakProp); // expected-note{{also accessed here}}
75 void implicitProperties(Test *a) {
76 use(a.implicitProp); // expected-warning{{weak implicit property 'implicitProp' is accessed multiple times}}
77 use(a.implicitProp); // expected-note{{also accessed here}}
80 void classProperties() {
81 use(Test.weakProp); // expected-warning{{weak implicit property 'weakProp' is accessed multiple times}}
82 use(Test.weakProp); // expected-note{{also accessed here}}
85 void classPropertiesAreDifferent(Test *a) {
86 use(Test.weakProp); // no-warning
87 use(a.weakProp); // no-warning
88 use(a.strongProp.weakProp); // no-warning
92 use(a->weakIvar); // expected-warning{{weak instance variable 'weakIvar' is accessed multiple times}}
93 use(a->weakIvar); // expected-note{{also accessed here}}
98 use(a); // expected-warning{{weak variable 'a' is accessed multiple times}}
99 use(a); // expected-note{{also accessed here}}
102 void messageGetter(Test *a) {
103 use([a weakProp]); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
104 use([a weakProp]); // expected-note{{also accessed here}}
107 void messageSetter(Test *a) {
108 [a setWeakProp:get()]; // no-warning
109 [a setWeakProp:get()]; // no-warning
112 void messageSetterAndGetter(Test *a) {
113 [a setWeakProp:get()]; // expected-note{{also accessed here}}
114 use([a weakProp]); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
117 void mixDotAndMessageSend(Test *a, Test *b) {
118 use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
119 use([a weakProp]); // expected-note{{also accessed here}}
121 use([b weakProp]); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
122 use(b.weakProp); // expected-note{{also accessed here}}
126 void assignToStrongWrongInit(Test *a) {
127 id val = a.weakProp; // expected-note{{also accessed here}}
128 use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
131 void assignToStrongWrong(Test *a) {
133 val = a.weakProp; // expected-note{{also accessed here}}
134 use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
137 void assignToIvarWrong(Test *a) {
138 a->weakIvar = get(); // expected-note{{also accessed here}}
139 use(a->weakIvar); // expected-warning{{weak instance variable 'weakIvar' is accessed multiple times}}
142 void assignToGlobalWrong() {
144 a = get(); // expected-note{{also accessed here}}
145 use(a); // expected-warning{{weak variable 'a' is accessed multiple times}}
148 void assignToStrongOK(Test *a) {
150 id val = a.weakProp; // no-warning
154 val = a.weakProp; // no-warning
159 void assignToStrongConditional(Test *a) {
160 id val = (condition() ? a.weakProp : a.weakProp); // no-warning
161 id val2 = a.implicitProp ?: a.implicitProp; // no-warning
164 void testBlock(Test *a) {
165 use(a.weakProp); // no-warning
168 use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times in this block}}
169 use(a.weakProp); // expected-note{{also accessed here}}
173 void assignToStrongWithCasts(Test *a) {
175 Test *val = (Test *)a.weakProp; // no-warning
179 val = (Test *)a.weakProp; // no-warning
184 void assignToStrongWithMessages(Test *a) {
186 id val = [a weakProp]; // no-warning
190 val = [a weakProp]; // no-warning
196 void assignAfterRead(Test *a) {
197 // Special exception for a single read before any writes.
198 if (!a.weakProp) // no-warning
199 a.weakProp = get(); // no-warning
202 void readOnceWriteMany(Test *a) {
203 if (!a.weakProp) { // no-warning
204 a.weakProp = get(); // no-warning
205 a.weakProp = get(); // no-warning
209 void readOnceAfterWrite(Test *a) {
210 a.weakProp = get(); // expected-note{{also accessed here}}
211 if (!a.weakProp) { // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}}
212 a.weakProp = get(); // expected-note{{also accessed here}}
216 void readOnceWriteManyLoops(Test *a, Test *b, Test *c, Test *d, Test *e) {
217 while (condition()) {
218 if (!a.weakProp) { // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}}
219 a.weakProp = get(); // expected-note{{also accessed here}}
220 a.weakProp = get(); // expected-note{{also accessed here}}
225 if (!b.weakProp) { // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}}
226 b.weakProp = get(); // expected-note{{also accessed here}}
227 b.weakProp = get(); // expected-note{{also accessed here}}
229 } while (condition());
231 for (id x = get(); x; x = get()) {
232 if (!c.weakProp) { // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}}
233 c.weakProp = get(); // expected-note{{also accessed here}}
234 c.weakProp = get(); // expected-note{{also accessed here}}
238 for (id x in get()) {
239 if (!d.weakProp) { // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}}
240 d.weakProp = get(); // expected-note{{also accessed here}}
241 d.weakProp = get(); // expected-note{{also accessed here}}
245 int array[] = { 1, 2, 3 };
246 for (int i : array) {
247 if (!e.weakProp) { // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}}
248 e.weakProp = get(); // expected-note{{also accessed here}}
249 e.weakProp = get(); // expected-note{{also accessed here}}
254 void readOnlyLoop(Test *a) {
255 while (condition()) {
256 use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}}
260 void readInIterationLoop() {
261 for (Test *a in get())
262 use(a.weakProp); // no-warning
265 void readDoubleLevelAccessInLoop() {
266 for (Test *a in get()) {
267 use(a.strongProp.weakProp); // no-warning
271 void readParameterInLoop(Test *a) {
272 for (id unused in get()) {
273 use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}}
278 void readGlobalInLoop() {
280 for (id unused in get()) {
281 use(a); // expected-warning{{weak variable 'a' is accessed multiple times in this function}}
286 void doWhileLoop(Test *a) {
288 use(a.weakProp); // no-warning
293 @interface Test (Methods)
296 @implementation Test (Methods)
298 use(self.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times in this method but may be unpredictably set to nil; assign to a strong variable to keep the object alive}}
299 use(self.weakProp); // expected-note{{also accessed here}}
303 use(weakIvar); // expected-warning{{weak instance variable 'weakIvar' is accessed multiple times in this method but may be unpredictably set to nil; assign to a strong variable to keep the object alive}}
304 use(weakIvar); // expected-note{{also accessed here}}
307 - (void)doubleLevelAccessForSelf {
308 use(self.strongProp.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
309 use(self.strongProp.weakProp); // expected-note{{also accessed here}}
311 use(self->ivar.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
312 use(self->ivar.weakProp); // expected-note{{also accessed here}}
314 use(self->ivar->weakIvar); // expected-warning{{weak instance variable 'weakIvar' is accessed multiple times}}
315 use(self->ivar->weakIvar); // expected-note{{also accessed here}}
318 - (void)distinctFromOther:(Test *)other {
319 use(self.strongProp.weakProp); // no-warning
320 use(other.strongProp.weakProp); // no-warning
322 use(self->ivar.weakProp); // no-warning
323 use(other->ivar.weakProp); // no-warning
325 use(self.strongProp->weakIvar); // no-warning
326 use(other.strongProp->weakIvar); // no-warning
332 @interface Sub1 : Base1
338 void test1(Sub1 *s) {
343 @interface Base1(cat)
344 @property (weak) id prop;
347 void test2(Sub1 *s) {
348 // This does not warn because the "prop" in "Base1(cat)" was introduced
349 // after the method declaration and we don't find it as overridden.
350 // Always looking for overridden methods after the method declaration is expensive
351 // and it's not clear it is worth it currently.
362 use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times in this function but may be unpredictably set to nil; assign to a strong variable to keep the object alive}}
363 use(a.weakProp); // expected-note{{also accessed here}}
366 void distinctFromOther(Test *b, const Wrapper &w) {
367 use(a.weakProp); // no-warning
368 use(b.weakProp); // no-warning
369 use(w.a.weakProp); // no-warning
372 static void doubleLevelAccessField(const Wrapper &x, const Wrapper &y) {
373 use(x.a.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}
374 use(y.a.weakProp); // expected-note{{also accessed here}}
379 // -----------------------
381 // -----------------------
383 // Most of these would require flow-sensitive analysis to silence correctly.
385 void assignNil(Test *a) {
387 a.weakProp = nil; // expected-note{{also accessed here}}
389 use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
392 void branch(Test *a) {
394 use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
396 use(a.weakProp); // expected-note{{also accessed here}}
399 void doubleLevelAccess(Test *a, Test *b) {
400 use(a.strongProp.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}
401 use(b.strongProp.weakProp); // expected-note{{also accessed here}}
403 use(a.weakProp.weakProp); // no-warning
406 void doubleLevelAccessIvar(Test *a, Test *b) {
407 use(a->ivar.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}
408 use(b->ivar.weakProp); // expected-note{{also accessed here}}
410 use(a.strongProp.weakProp); // no-warning