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 basicCorrectnessTest(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
302 void test_list_init(C *c) {
306 @interface Test (Methods)
309 @implementation Test (Methods)
310 - (void)basicCorrectnessTest {
311 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}}
312 use(self.weakProp); // expected-note{{also accessed here}}
316 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}}
317 use(weakIvar); // expected-note{{also accessed here}}
320 - (void)doubleLevelAccessForSelf {
321 use(self.strongProp.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
322 use(self.strongProp.weakProp); // expected-note{{also accessed here}}
324 use(self->ivar.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
325 use(self->ivar.weakProp); // expected-note{{also accessed here}}
327 use(self->ivar->weakIvar); // expected-warning{{weak instance variable 'weakIvar' is accessed multiple times}}
328 use(self->ivar->weakIvar); // expected-note{{also accessed here}}
331 - (void)distinctFromOther:(Test *)other {
332 use(self.strongProp.weakProp); // no-warning
333 use(other.strongProp.weakProp); // no-warning
335 use(self->ivar.weakProp); // no-warning
336 use(other->ivar.weakProp); // no-warning
338 use(self.strongProp->weakIvar); // no-warning
339 use(other.strongProp->weakIvar); // no-warning
345 @interface Sub1 : Base1
351 void test1(Sub1 *s) {
356 @interface Base1(cat)
357 @property (weak) id prop;
360 void test2(Sub1 *s) {
361 // This does not warn because the "prop" in "Base1(cat)" was introduced
362 // after the method declaration and we don't find it as overridden.
363 // Always looking for overridden methods after the method declaration is expensive
364 // and it's not clear it is worth it currently.
375 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}}
376 use(a.weakProp); // expected-note{{also accessed here}}
379 void distinctFromOther(Test *b, const Wrapper &w) {
380 use(a.weakProp); // no-warning
381 use(b.weakProp); // no-warning
382 use(w.a.weakProp); // no-warning
385 static void doubleLevelAccessField(const Wrapper &x, const Wrapper &y) {
386 use(x.a.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}
387 use(y.a.weakProp); // expected-note{{also accessed here}}
392 // -----------------------
394 // -----------------------
396 // Most of these would require flow-sensitive analysis to silence correctly.
398 void assignNil(Test *a) {
400 a.weakProp = nil; // expected-note{{also accessed here}}
402 use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
405 void branch(Test *a) {
407 use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
409 use(a.weakProp); // expected-note{{also accessed here}}
412 void doubleLevelAccess(Test *a, Test *b) {
413 use(a.strongProp.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}
414 use(b.strongProp.weakProp); // expected-note{{also accessed here}}
416 use(a.weakProp.weakProp); // no-warning
419 void doubleLevelAccessIvar(Test *a, Test *b) {
420 use(a->ivar.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}
421 use(b->ivar.weakProp); // expected-note{{also accessed here}}
423 use(a.strongProp.weakProp); // no-warning
430 - (int) warningAboutWeakVariableInsideTypeof {
431 __typeof__(self) __weak weakSelf = self;
433 __typeof__(weakSelf) blockSelf = weakSelf;
436 return sizeof(weakSelf);
447 - (void) Meth : (id) data
449 data = data ?: NSNull.null;
453 // This used to crash in WeakObjectProfileTy::getBaseInfo when getBase() was
454 // called on an ObjCPropertyRefExpr object whose receiver was an interface.
459 @property (class, strong) NSBundle *foo2;
460 @property (strong) NSString *prop;
461 @property(weak) NSString *weakProp;
464 @interface NSBundle2 : NSBundle
468 NSString * t = NSBundle.foo.prop;
469 use(NSBundle.foo.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}
470 use(NSBundle2.foo.weakProp); // expected-note{{also accessed here}}
472 NSString * t2 = NSBundle.foo2.prop;
473 use(NSBundle.foo2.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}
474 use(NSBundle2.foo2.weakProp); // expected-note{{also accessed here}}
475 decltype([NSBundle2.foo2 weakProp]) t3;
476 decltype(NSBundle2.foo2.weakProp) t4;
477 __typeof__(NSBundle2.foo2.weakProp) t5;
480 // This used to crash in the constructor of WeakObjectProfileTy when a
481 // DeclRefExpr was passed that didn't reference a VarDecl.
483 typedef INTF * INTFPtrTy;
490 INTFPtrTy tmp = (INTFPtrTy)e1;
491 #if __has_feature(objc_arc)
492 // expected-error@-2{{cast of 'E' to 'INTFPtrTy' (aka 'INTF *') is disallowed with ARC}}
497 static NSString* const kGlobal = @"";
499 @interface NSDictionary
500 - (id)objectForKeyedSubscript:(id)key;
504 @property (weak) NSDictionary *nd;
507 @implementation WeakProp
509 (void)self.nd[@""]; // no warning