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
9 @property(weak) Test *weakProp;
10 @property(strong) Test *strongProp;
12 - (__weak id)implicitProp;
14 + (__weak id)weakProp;
19 extern bool condition();
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}}
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
42 a.weakProp = next; // no-warning
44 a->weakIvar = get(); // no-warning
47 a->weakIvar = next; // no-warning
50 x = get(); // no-warning
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
93 use(a->weakIvar); // expected-warning{{weak instance variable 'weakIvar' is accessed multiple times}}
94 use(a->weakIvar); // expected-note{{also accessed here}}
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) {
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() {
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) {
151 id val = a.weakProp; // no-warning
155 val = a.weakProp; // no-warning
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
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}}
174 void assignToStrongWithCasts(Test *a) {
176 Test *val = (Test *)a.weakProp; // no-warning
180 val = (Test *)a.weakProp; // no-warning
185 void assignToStrongWithMessages(Test *a) {
187 id val = [a weakProp]; // no-warning
191 val = [a weakProp]; // no-warning
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
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}}
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}}
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}}
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}}
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}}
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}}
255 void readOnlyLoop(Test *a) {
256 while (condition()) {
257 use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}}
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
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}}
279 void readGlobalInLoop() {
281 for (id unused in get()) {
282 use(a); // expected-warning{{weak variable 'a' is accessed multiple times in this function}}
287 void doWhileLoop(Test *a) {
289 use(a.weakProp); // no-warning
294 @interface Test (Methods)
297 @implementation Test (Methods)
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}}
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
333 @interface Sub1 : Base1
339 void test1(Sub1 *s) {
344 @interface Base1(cat)
345 @property (weak) id prop;
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.
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}}
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
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}}
380 // -----------------------
382 // -----------------------
384 // Most of these would require flow-sensitive analysis to silence correctly.
386 void assignNil(Test *a) {
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) {
395 use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
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
419 - (int) warningAboutWeakVariableInsideTypeof {
420 __typeof__(self) __weak weakSelf = self;
422 __typeof__(weakSelf) blockSelf = weakSelf;
425 return sizeof(weakSelf);
437 - (void) Meth : (id) data
439 data = data ?: NSNull.null;
443 // This used to crash in WeakObjectProfileTy::getBaseInfo when getBase() was
444 // called on an ObjCPropertyRefExpr object whose receiver was an interface.
449 @property (class, strong) NSBundle *foo2;
450 @property (strong) NSString *prop;
451 @property(weak) NSString *weakProp;
454 @interface NSBundle2 : NSBundle
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;
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}}
487 static NSString* const kGlobal = @"";