[PowerPC] Collect some CallLowering arguments into a struct. [NFC]
[llvm-project.git] / clang / test / SemaObjC / arc-repeated-weak.mm
blob4eec4d2fe69c790157fac9ecbcd58e1a593386a2
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
2 // RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-weak -fblocks -Wno-objc-root-class -std=c++11 -Warc-repeated-use-of-weak -verify %s
4 @interface Test {
5 @public
6   Test *ivar;
7   __weak id weakIvar;
9 @property(weak) Test *weakProp;
10 @property(strong) Test *strongProp;
12 - (__weak id)implicitProp;
14 + (__weak id)weakProp;
15 @end
17 extern void use(id);
18 extern id get();
19 extern bool condition();
20 #define nil ((id)0)
22 void sanity(Test *a) {
23   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}}
24   use(a.weakProp); // expected-note{{also accessed here}}
26   use(a.strongProp);
27   use(a.strongProp); // no-warning
29   use(a.weakProp); // expected-note{{also accessed here}}
32 void singleUse(Test *a) {
33   use(a.weakProp); // no-warning
34   use(a.strongProp); // no-warning
37 void assignsOnly(Test *a) {
38   a.weakProp = get(); // no-warning
40   id next = get();
41   if (next)
42     a.weakProp = next; // no-warning
44   a->weakIvar = get(); // no-warning
45   next = get();
46   if (next)
47     a->weakIvar = next; // no-warning
49   extern __weak id x;
50   x = get(); // no-warning
51   next = get();
52   if (next)
53     x = next; // no-warning
56 void assignThenRead(Test *a) {
57   a.weakProp = get(); // expected-note{{also accessed here}}
58   use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
61 void twoVariables(Test *a, Test *b) {
62   use(a.weakProp); // no-warning
63   use(b.weakProp); // no-warning
66 void doubleLevelAccess(Test *a) {
67   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}}
68   use(a.strongProp.weakProp); // expected-note{{also accessed here}}
71 void doubleLevelAccessIvar(Test *a) {
72   use(a.strongProp.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}
73   use(a.strongProp.weakProp); // expected-note{{also accessed here}}
76 void implicitProperties(Test *a) {
77   use(a.implicitProp); // expected-warning{{weak implicit property 'implicitProp' is accessed multiple times}}
78   use(a.implicitProp); // expected-note{{also accessed here}}
81 void classProperties() {
82   use(Test.weakProp); // expected-warning{{weak implicit property 'weakProp' is accessed multiple times}}
83   use(Test.weakProp); // expected-note{{also accessed here}}
86 void classPropertiesAreDifferent(Test *a) {
87   use(Test.weakProp); // no-warning
88   use(a.weakProp); // no-warning
89   use(a.strongProp.weakProp); // no-warning
92 void ivars(Test *a) {
93   use(a->weakIvar); // expected-warning{{weak instance variable 'weakIvar' is accessed multiple times}}
94   use(a->weakIvar); // expected-note{{also accessed here}}
97 void globals() {
98   extern __weak id a;
99   use(a); // expected-warning{{weak variable 'a' is accessed multiple times}}
100   use(a); // expected-note{{also accessed here}}
103 void messageGetter(Test *a) {
104   use([a weakProp]); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
105   use([a weakProp]); // expected-note{{also accessed here}}
108 void messageSetter(Test *a) {
109   [a setWeakProp:get()]; // no-warning
110   [a setWeakProp:get()]; // no-warning
113 void messageSetterAndGetter(Test *a) {
114   [a setWeakProp:get()]; // expected-note{{also accessed here}}
115   use([a weakProp]); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
118 void mixDotAndMessageSend(Test *a, Test *b) {
119   use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
120   use([a weakProp]); // expected-note{{also accessed here}}
122   use([b weakProp]); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
123   use(b.weakProp); // expected-note{{also accessed here}}
127 void assignToStrongWrongInit(Test *a) {
128   id val = a.weakProp; // expected-note{{also accessed here}}
129   use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
132 void assignToStrongWrong(Test *a) {
133   id val;
134   val = a.weakProp; // expected-note{{also accessed here}}
135   use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
138 void assignToIvarWrong(Test *a) {
139   a->weakIvar = get(); // expected-note{{also accessed here}}
140   use(a->weakIvar); // expected-warning{{weak instance variable 'weakIvar' is accessed multiple times}}
143 void assignToGlobalWrong() {
144   extern __weak id a;
145   a = get(); // expected-note{{also accessed here}}
146   use(a); // expected-warning{{weak variable 'a' is accessed multiple times}}
149 void assignToStrongOK(Test *a) {
150   if (condition()) {
151     id val = a.weakProp; // no-warning
152     (void)val;
153   } else {
154     id val;
155     val = a.weakProp; // no-warning
156     (void)val;
157   }
160 void assignToStrongConditional(Test *a) {
161   id val = (condition() ? a.weakProp : a.weakProp); // no-warning
162   id val2 = a.implicitProp ?: a.implicitProp; // no-warning
165 void testBlock(Test *a) {
166   use(a.weakProp); // no-warning
168   use(^{
169     use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times in this block}}
170     use(a.weakProp); // expected-note{{also accessed here}}
171   });
174 void assignToStrongWithCasts(Test *a) {
175   if (condition()) {
176     Test *val = (Test *)a.weakProp; // no-warning
177     (void)val;
178   } else {
179     id val;
180     val = (Test *)a.weakProp; // no-warning
181     (void)val;
182   }
185 void assignToStrongWithMessages(Test *a) {
186   if (condition()) {
187     id val = [a weakProp]; // no-warning
188     (void)val;
189   } else {
190     id val;
191     val = [a weakProp]; // no-warning
192     (void)val;
193   }
197 void assignAfterRead(Test *a) {
198   // Special exception for a single read before any writes.
199   if (!a.weakProp) // no-warning
200     a.weakProp = get(); // no-warning
203 void readOnceWriteMany(Test *a) {
204   if (!a.weakProp) { // no-warning
205     a.weakProp = get(); // no-warning
206     a.weakProp = get(); // no-warning
207   }
210 void readOnceAfterWrite(Test *a) {
211   a.weakProp = get(); // expected-note{{also accessed here}}
212   if (!a.weakProp) { // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}}
213     a.weakProp = get(); // expected-note{{also accessed here}}
214   }
217 void readOnceWriteManyLoops(Test *a, Test *b, Test *c, Test *d, Test *e) {
218   while (condition()) {
219     if (!a.weakProp) { // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}}
220       a.weakProp = get(); // expected-note{{also accessed here}}
221       a.weakProp = get(); // expected-note{{also accessed here}}
222     }
223   }
225   do {
226     if (!b.weakProp) { // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}}
227       b.weakProp = get(); // expected-note{{also accessed here}}
228       b.weakProp = get(); // expected-note{{also accessed here}}
229     }
230   } while (condition());
232   for (id x = get(); x; x = get()) {
233     if (!c.weakProp) { // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}}
234       c.weakProp = get(); // expected-note{{also accessed here}}
235       c.weakProp = get(); // expected-note{{also accessed here}}
236     }
237   }
239   for (id x in get()) {
240     if (!d.weakProp) { // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}}
241       d.weakProp = get(); // expected-note{{also accessed here}}
242       d.weakProp = get(); // expected-note{{also accessed here}}
243     }
244   }
246   int array[] = { 1, 2, 3 };
247   for (int i : array) {
248     if (!e.weakProp) { // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}}
249       e.weakProp = get(); // expected-note{{also accessed here}}
250       e.weakProp = get(); // expected-note{{also accessed here}}
251     }
252   }
255 void readOnlyLoop(Test *a) {
256   while (condition()) {
257     use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}}
258   }
261 void readInIterationLoop() {
262   for (Test *a in get())
263     use(a.weakProp); // no-warning
266 void readDoubleLevelAccessInLoop() {
267   for (Test *a in get()) {
268     use(a.strongProp.weakProp); // no-warning
269   }
272 void readParameterInLoop(Test *a) {
273   for (id unused in get()) {
274     use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}}
275     (void)unused;
276   }
279 void readGlobalInLoop() {
280   static __weak id a;
281   for (id unused in get()) {
282     use(a); // expected-warning{{weak variable 'a' is accessed multiple times in this function}}
283     (void)unused;
284   }
287 void doWhileLoop(Test *a) {
288   do {
289     use(a.weakProp); // no-warning
290   } while(0);
294 @interface Test (Methods)
295 @end
297 @implementation Test (Methods)
298 - (void)sanity {
299   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}}
300   use(self.weakProp); // expected-note{{also accessed here}}
303 - (void)ivars {
304   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}}
305   use(weakIvar); // expected-note{{also accessed here}}
308 - (void)doubleLevelAccessForSelf {
309   use(self.strongProp.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
310   use(self.strongProp.weakProp); // expected-note{{also accessed here}}
312   use(self->ivar.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
313   use(self->ivar.weakProp); // expected-note{{also accessed here}}
315   use(self->ivar->weakIvar); // expected-warning{{weak instance variable 'weakIvar' is accessed multiple times}}
316   use(self->ivar->weakIvar); // expected-note{{also accessed here}}
319 - (void)distinctFromOther:(Test *)other {
320   use(self.strongProp.weakProp); // no-warning
321   use(other.strongProp.weakProp); // no-warning
323   use(self->ivar.weakProp); // no-warning
324   use(other->ivar.weakProp); // no-warning
326   use(self.strongProp->weakIvar); // no-warning
327   use(other.strongProp->weakIvar); // no-warning
329 @end
331 @interface Base1
332 @end
333 @interface Sub1 : Base1
334 @end
335 @interface Sub1(cat)
336 -(id)prop;
337 @end
339 void test1(Sub1 *s) {
340   use([s prop]);
341   use([s prop]);
344 @interface Base1(cat)
345 @property (weak) id prop;
346 @end
348 void test2(Sub1 *s) {
349   // This does not warn because the "prop" in "Base1(cat)" was introduced
350   // after the method declaration and we don't find it as overridden.
351   // Always looking for overridden methods after the method declaration is expensive
352   // and it's not clear it is worth it currently.
353   use([s prop]);
354   use([s prop]);
358 class Wrapper {
359   Test *a;
361 public:
362   void fields() {
363     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}}
364     use(a.weakProp); // expected-note{{also accessed here}}
365   }
367   void distinctFromOther(Test *b, const Wrapper &w) {
368     use(a.weakProp); // no-warning
369     use(b.weakProp); // no-warning
370     use(w.a.weakProp); // no-warning
371   }
373   static void doubleLevelAccessField(const Wrapper &x, const Wrapper &y) {
374     use(x.a.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}
375     use(y.a.weakProp); // expected-note{{also accessed here}}
376   }
380 // -----------------------
381 // False positives
382 // -----------------------
384 // Most of these would require flow-sensitive analysis to silence correctly.
386 void assignNil(Test *a) {
387   if (condition())
388     a.weakProp = nil; // expected-note{{also accessed here}}
390   use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
393 void branch(Test *a) {
394   if (condition())
395     use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
396   else
397     use(a.weakProp); // expected-note{{also accessed here}}
400 void doubleLevelAccess(Test *a, Test *b) {
401   use(a.strongProp.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}
402   use(b.strongProp.weakProp); // expected-note{{also accessed here}}
404   use(a.weakProp.weakProp); // no-warning
407 void doubleLevelAccessIvar(Test *a, Test *b) {
408   use(a->ivar.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}
409   use(b->ivar.weakProp); // expected-note{{also accessed here}}
411   use(a.strongProp.weakProp); // no-warning
414 // rdar://13942025
415 @interface X
416 @end
418 @implementation X
419 - (int) warningAboutWeakVariableInsideTypeof {
420     __typeof__(self) __weak weakSelf = self;
421     ^(){
422         __typeof__(weakSelf) blockSelf = weakSelf;
423         use(blockSelf);
424     }();
425     return sizeof(weakSelf);
427 @end
429 // rdar://19053620
430 @interface NSNull
431 + (NSNull *)null;
432 @end
434 @interface INTF @end
436 @implementation INTF
437 - (void) Meth : (id) data
439   data = data ?: NSNull.null;
441 @end
443 // This used to crash in WeakObjectProfileTy::getBaseInfo when getBase() was
444 // called on an ObjCPropertyRefExpr object whose receiver was an interface.
446 @class NSString;
447 @interface NSBundle
448 +(NSBundle *)foo;
449 @property (class, strong) NSBundle *foo2;
450 @property (strong) NSString *prop;
451 @property(weak) NSString *weakProp;
452 @end
454 @interface NSBundle2 : NSBundle
455 @end
457 void foo() {
458   NSString * t = NSBundle.foo.prop;
459   use(NSBundle.foo.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}
460   use(NSBundle2.foo.weakProp); // expected-note{{also accessed here}}
462   NSString * t2 = NSBundle.foo2.prop;
463   use(NSBundle.foo2.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}
464   use(NSBundle2.foo2.weakProp); // expected-note{{also accessed here}}
465   decltype([NSBundle2.foo2 weakProp]) t3;
466   decltype(NSBundle2.foo2.weakProp) t4;
467   __typeof__(NSBundle2.foo2.weakProp) t5;
470 // This used to crash in the constructor of WeakObjectProfileTy when a
471 // DeclRefExpr was passed that didn't reference a VarDecl.
473 typedef INTF * INTFPtrTy;
475 enum E {
476   e1
479 void foo1() {
480   INTFPtrTy tmp = (INTFPtrTy)e1;
481 #if __has_feature(objc_arc)
482 // expected-error@-2{{cast of 'E' to 'INTFPtrTy' (aka 'INTF *') is disallowed with ARC}}
483 #endif
486 @class NSString;
487 static NSString* const kGlobal = @"";