xref: /aosp_15_r20/external/clang/test/SemaObjC/arc-repeated-weak.mm (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li// 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*67e74705SXin Li
3*67e74705SXin Li@interface Test {
4*67e74705SXin Li@public
5*67e74705SXin Li  Test *ivar;
6*67e74705SXin Li  __weak id weakIvar;
7*67e74705SXin Li}
8*67e74705SXin Li@property(weak) Test *weakProp;
9*67e74705SXin Li@property(strong) Test *strongProp;
10*67e74705SXin Li
11*67e74705SXin Li- (__weak id)implicitProp;
12*67e74705SXin Li
13*67e74705SXin Li+ (__weak id)weakProp;
14*67e74705SXin Li@end
15*67e74705SXin Li
16*67e74705SXin Liextern void use(id);
17*67e74705SXin Liextern id get();
18*67e74705SXin Liextern bool condition();
19*67e74705SXin Li#define nil ((id)0)
20*67e74705SXin Li
21*67e74705SXin Livoid sanity(Test *a) {
22*67e74705SXin Li  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*67e74705SXin Li  use(a.weakProp); // expected-note{{also accessed here}}
24*67e74705SXin Li
25*67e74705SXin Li  use(a.strongProp);
26*67e74705SXin Li  use(a.strongProp); // no-warning
27*67e74705SXin Li
28*67e74705SXin Li  use(a.weakProp); // expected-note{{also accessed here}}
29*67e74705SXin Li}
30*67e74705SXin Li
31*67e74705SXin Livoid singleUse(Test *a) {
32*67e74705SXin Li  use(a.weakProp); // no-warning
33*67e74705SXin Li  use(a.strongProp); // no-warning
34*67e74705SXin Li}
35*67e74705SXin Li
36*67e74705SXin Livoid assignsOnly(Test *a) {
37*67e74705SXin Li  a.weakProp = get(); // no-warning
38*67e74705SXin Li
39*67e74705SXin Li  id next = get();
40*67e74705SXin Li  if (next)
41*67e74705SXin Li    a.weakProp = next; // no-warning
42*67e74705SXin Li
43*67e74705SXin Li  a->weakIvar = get(); // no-warning
44*67e74705SXin Li  next = get();
45*67e74705SXin Li  if (next)
46*67e74705SXin Li    a->weakIvar = next; // no-warning
47*67e74705SXin Li
48*67e74705SXin Li  extern __weak id x;
49*67e74705SXin Li  x = get(); // no-warning
50*67e74705SXin Li  next = get();
51*67e74705SXin Li  if (next)
52*67e74705SXin Li    x = next; // no-warning
53*67e74705SXin Li}
54*67e74705SXin Li
55*67e74705SXin Livoid assignThenRead(Test *a) {
56*67e74705SXin Li  a.weakProp = get(); // expected-note{{also accessed here}}
57*67e74705SXin Li  use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
58*67e74705SXin Li}
59*67e74705SXin Li
60*67e74705SXin Livoid twoVariables(Test *a, Test *b) {
61*67e74705SXin Li  use(a.weakProp); // no-warning
62*67e74705SXin Li  use(b.weakProp); // no-warning
63*67e74705SXin Li}
64*67e74705SXin Li
65*67e74705SXin Livoid doubleLevelAccess(Test *a) {
66*67e74705SXin Li  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*67e74705SXin Li  use(a.strongProp.weakProp); // expected-note{{also accessed here}}
68*67e74705SXin Li}
69*67e74705SXin Li
70*67e74705SXin Livoid doubleLevelAccessIvar(Test *a) {
71*67e74705SXin Li  use(a.strongProp.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}
72*67e74705SXin Li  use(a.strongProp.weakProp); // expected-note{{also accessed here}}
73*67e74705SXin Li}
74*67e74705SXin Li
75*67e74705SXin Livoid implicitProperties(Test *a) {
76*67e74705SXin Li  use(a.implicitProp); // expected-warning{{weak implicit property 'implicitProp' is accessed multiple times}}
77*67e74705SXin Li  use(a.implicitProp); // expected-note{{also accessed here}}
78*67e74705SXin Li}
79*67e74705SXin Li
80*67e74705SXin Livoid classProperties() {
81*67e74705SXin Li  use(Test.weakProp); // expected-warning{{weak implicit property 'weakProp' is accessed multiple times}}
82*67e74705SXin Li  use(Test.weakProp); // expected-note{{also accessed here}}
83*67e74705SXin Li}
84*67e74705SXin Li
85*67e74705SXin Livoid classPropertiesAreDifferent(Test *a) {
86*67e74705SXin Li  use(Test.weakProp); // no-warning
87*67e74705SXin Li  use(a.weakProp); // no-warning
88*67e74705SXin Li  use(a.strongProp.weakProp); // no-warning
89*67e74705SXin Li}
90*67e74705SXin Li
91*67e74705SXin Livoid ivars(Test *a) {
92*67e74705SXin Li  use(a->weakIvar); // expected-warning{{weak instance variable 'weakIvar' is accessed multiple times}}
93*67e74705SXin Li  use(a->weakIvar); // expected-note{{also accessed here}}
94*67e74705SXin Li}
95*67e74705SXin Li
96*67e74705SXin Livoid globals() {
97*67e74705SXin Li  extern __weak id a;
98*67e74705SXin Li  use(a); // expected-warning{{weak variable 'a' is accessed multiple times}}
99*67e74705SXin Li  use(a); // expected-note{{also accessed here}}
100*67e74705SXin Li}
101*67e74705SXin Li
102*67e74705SXin Livoid messageGetter(Test *a) {
103*67e74705SXin Li  use([a weakProp]); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
104*67e74705SXin Li  use([a weakProp]); // expected-note{{also accessed here}}
105*67e74705SXin Li}
106*67e74705SXin Li
107*67e74705SXin Livoid messageSetter(Test *a) {
108*67e74705SXin Li  [a setWeakProp:get()]; // no-warning
109*67e74705SXin Li  [a setWeakProp:get()]; // no-warning
110*67e74705SXin Li}
111*67e74705SXin Li
112*67e74705SXin Livoid messageSetterAndGetter(Test *a) {
113*67e74705SXin Li  [a setWeakProp:get()]; // expected-note{{also accessed here}}
114*67e74705SXin Li  use([a weakProp]); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
115*67e74705SXin Li}
116*67e74705SXin Li
117*67e74705SXin Livoid mixDotAndMessageSend(Test *a, Test *b) {
118*67e74705SXin Li  use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
119*67e74705SXin Li  use([a weakProp]); // expected-note{{also accessed here}}
120*67e74705SXin Li
121*67e74705SXin Li  use([b weakProp]); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
122*67e74705SXin Li  use(b.weakProp); // expected-note{{also accessed here}}
123*67e74705SXin Li}
124*67e74705SXin Li
125*67e74705SXin Li
126*67e74705SXin Livoid assignToStrongWrongInit(Test *a) {
127*67e74705SXin Li  id val = a.weakProp; // expected-note{{also accessed here}}
128*67e74705SXin Li  use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
129*67e74705SXin Li}
130*67e74705SXin Li
131*67e74705SXin Livoid assignToStrongWrong(Test *a) {
132*67e74705SXin Li  id val;
133*67e74705SXin Li  val = a.weakProp; // expected-note{{also accessed here}}
134*67e74705SXin Li  use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
135*67e74705SXin Li}
136*67e74705SXin Li
137*67e74705SXin Livoid assignToIvarWrong(Test *a) {
138*67e74705SXin Li  a->weakIvar = get(); // expected-note{{also accessed here}}
139*67e74705SXin Li  use(a->weakIvar); // expected-warning{{weak instance variable 'weakIvar' is accessed multiple times}}
140*67e74705SXin Li}
141*67e74705SXin Li
142*67e74705SXin Livoid assignToGlobalWrong() {
143*67e74705SXin Li  extern __weak id a;
144*67e74705SXin Li  a = get(); // expected-note{{also accessed here}}
145*67e74705SXin Li  use(a); // expected-warning{{weak variable 'a' is accessed multiple times}}
146*67e74705SXin Li}
147*67e74705SXin Li
148*67e74705SXin Livoid assignToStrongOK(Test *a) {
149*67e74705SXin Li  if (condition()) {
150*67e74705SXin Li    id val = a.weakProp; // no-warning
151*67e74705SXin Li    (void)val;
152*67e74705SXin Li  } else {
153*67e74705SXin Li    id val;
154*67e74705SXin Li    val = a.weakProp; // no-warning
155*67e74705SXin Li    (void)val;
156*67e74705SXin Li  }
157*67e74705SXin Li}
158*67e74705SXin Li
159*67e74705SXin Livoid assignToStrongConditional(Test *a) {
160*67e74705SXin Li  id val = (condition() ? a.weakProp : a.weakProp); // no-warning
161*67e74705SXin Li  id val2 = a.implicitProp ?: a.implicitProp; // no-warning
162*67e74705SXin Li}
163*67e74705SXin Li
164*67e74705SXin Livoid testBlock(Test *a) {
165*67e74705SXin Li  use(a.weakProp); // no-warning
166*67e74705SXin Li
167*67e74705SXin Li  use(^{
168*67e74705SXin Li    use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times in this block}}
169*67e74705SXin Li    use(a.weakProp); // expected-note{{also accessed here}}
170*67e74705SXin Li  });
171*67e74705SXin Li}
172*67e74705SXin Li
173*67e74705SXin Livoid assignToStrongWithCasts(Test *a) {
174*67e74705SXin Li  if (condition()) {
175*67e74705SXin Li    Test *val = (Test *)a.weakProp; // no-warning
176*67e74705SXin Li    (void)val;
177*67e74705SXin Li  } else {
178*67e74705SXin Li    id val;
179*67e74705SXin Li    val = (Test *)a.weakProp; // no-warning
180*67e74705SXin Li    (void)val;
181*67e74705SXin Li  }
182*67e74705SXin Li}
183*67e74705SXin Li
184*67e74705SXin Livoid assignToStrongWithMessages(Test *a) {
185*67e74705SXin Li  if (condition()) {
186*67e74705SXin Li    id val = [a weakProp]; // no-warning
187*67e74705SXin Li    (void)val;
188*67e74705SXin Li  } else {
189*67e74705SXin Li    id val;
190*67e74705SXin Li    val = [a weakProp]; // no-warning
191*67e74705SXin Li    (void)val;
192*67e74705SXin Li  }
193*67e74705SXin Li}
194*67e74705SXin Li
195*67e74705SXin Li
196*67e74705SXin Livoid assignAfterRead(Test *a) {
197*67e74705SXin Li  // Special exception for a single read before any writes.
198*67e74705SXin Li  if (!a.weakProp) // no-warning
199*67e74705SXin Li    a.weakProp = get(); // no-warning
200*67e74705SXin Li}
201*67e74705SXin Li
202*67e74705SXin Livoid readOnceWriteMany(Test *a) {
203*67e74705SXin Li  if (!a.weakProp) { // no-warning
204*67e74705SXin Li    a.weakProp = get(); // no-warning
205*67e74705SXin Li    a.weakProp = get(); // no-warning
206*67e74705SXin Li  }
207*67e74705SXin Li}
208*67e74705SXin Li
209*67e74705SXin Livoid readOnceAfterWrite(Test *a) {
210*67e74705SXin Li  a.weakProp = get(); // expected-note{{also accessed here}}
211*67e74705SXin Li  if (!a.weakProp) { // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}}
212*67e74705SXin Li    a.weakProp = get(); // expected-note{{also accessed here}}
213*67e74705SXin Li  }
214*67e74705SXin Li}
215*67e74705SXin Li
216*67e74705SXin Livoid readOnceWriteManyLoops(Test *a, Test *b, Test *c, Test *d, Test *e) {
217*67e74705SXin Li  while (condition()) {
218*67e74705SXin Li    if (!a.weakProp) { // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}}
219*67e74705SXin Li      a.weakProp = get(); // expected-note{{also accessed here}}
220*67e74705SXin Li      a.weakProp = get(); // expected-note{{also accessed here}}
221*67e74705SXin Li    }
222*67e74705SXin Li  }
223*67e74705SXin Li
224*67e74705SXin Li  do {
225*67e74705SXin Li    if (!b.weakProp) { // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}}
226*67e74705SXin Li      b.weakProp = get(); // expected-note{{also accessed here}}
227*67e74705SXin Li      b.weakProp = get(); // expected-note{{also accessed here}}
228*67e74705SXin Li    }
229*67e74705SXin Li  } while (condition());
230*67e74705SXin Li
231*67e74705SXin Li  for (id x = get(); x; x = get()) {
232*67e74705SXin Li    if (!c.weakProp) { // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}}
233*67e74705SXin Li      c.weakProp = get(); // expected-note{{also accessed here}}
234*67e74705SXin Li      c.weakProp = get(); // expected-note{{also accessed here}}
235*67e74705SXin Li    }
236*67e74705SXin Li  }
237*67e74705SXin Li
238*67e74705SXin Li  for (id x in get()) {
239*67e74705SXin Li    if (!d.weakProp) { // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}}
240*67e74705SXin Li      d.weakProp = get(); // expected-note{{also accessed here}}
241*67e74705SXin Li      d.weakProp = get(); // expected-note{{also accessed here}}
242*67e74705SXin Li    }
243*67e74705SXin Li  }
244*67e74705SXin Li
245*67e74705SXin Li  int array[] = { 1, 2, 3 };
246*67e74705SXin Li  for (int i : array) {
247*67e74705SXin Li    if (!e.weakProp) { // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}}
248*67e74705SXin Li      e.weakProp = get(); // expected-note{{also accessed here}}
249*67e74705SXin Li      e.weakProp = get(); // expected-note{{also accessed here}}
250*67e74705SXin Li    }
251*67e74705SXin Li  }
252*67e74705SXin Li}
253*67e74705SXin Li
254*67e74705SXin Livoid readOnlyLoop(Test *a) {
255*67e74705SXin Li  while (condition()) {
256*67e74705SXin Li    use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}}
257*67e74705SXin Li  }
258*67e74705SXin Li}
259*67e74705SXin Li
260*67e74705SXin Livoid readInIterationLoop() {
261*67e74705SXin Li  for (Test *a in get())
262*67e74705SXin Li    use(a.weakProp); // no-warning
263*67e74705SXin Li}
264*67e74705SXin Li
265*67e74705SXin Livoid readDoubleLevelAccessInLoop() {
266*67e74705SXin Li  for (Test *a in get()) {
267*67e74705SXin Li    use(a.strongProp.weakProp); // no-warning
268*67e74705SXin Li  }
269*67e74705SXin Li}
270*67e74705SXin Li
271*67e74705SXin Livoid readParameterInLoop(Test *a) {
272*67e74705SXin Li  for (id unused in get()) {
273*67e74705SXin Li    use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times in this function}}
274*67e74705SXin Li    (void)unused;
275*67e74705SXin Li  }
276*67e74705SXin Li}
277*67e74705SXin Li
278*67e74705SXin Livoid readGlobalInLoop() {
279*67e74705SXin Li  static __weak id a;
280*67e74705SXin Li  for (id unused in get()) {
281*67e74705SXin Li    use(a); // expected-warning{{weak variable 'a' is accessed multiple times in this function}}
282*67e74705SXin Li    (void)unused;
283*67e74705SXin Li  }
284*67e74705SXin Li}
285*67e74705SXin Li
286*67e74705SXin Livoid doWhileLoop(Test *a) {
287*67e74705SXin Li  do {
288*67e74705SXin Li    use(a.weakProp); // no-warning
289*67e74705SXin Li  } while(0);
290*67e74705SXin Li}
291*67e74705SXin Li
292*67e74705SXin Li
293*67e74705SXin Li@interface Test (Methods)
294*67e74705SXin Li@end
295*67e74705SXin Li
296*67e74705SXin Li@implementation Test (Methods)
297*67e74705SXin Li- (void)sanity {
298*67e74705SXin Li  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*67e74705SXin Li  use(self.weakProp); // expected-note{{also accessed here}}
300*67e74705SXin Li}
301*67e74705SXin Li
302*67e74705SXin Li- (void)ivars {
303*67e74705SXin Li  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*67e74705SXin Li  use(weakIvar); // expected-note{{also accessed here}}
305*67e74705SXin Li}
306*67e74705SXin Li
307*67e74705SXin Li- (void)doubleLevelAccessForSelf {
308*67e74705SXin Li  use(self.strongProp.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
309*67e74705SXin Li  use(self.strongProp.weakProp); // expected-note{{also accessed here}}
310*67e74705SXin Li
311*67e74705SXin Li  use(self->ivar.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
312*67e74705SXin Li  use(self->ivar.weakProp); // expected-note{{also accessed here}}
313*67e74705SXin Li
314*67e74705SXin Li  use(self->ivar->weakIvar); // expected-warning{{weak instance variable 'weakIvar' is accessed multiple times}}
315*67e74705SXin Li  use(self->ivar->weakIvar); // expected-note{{also accessed here}}
316*67e74705SXin Li}
317*67e74705SXin Li
318*67e74705SXin Li- (void)distinctFromOther:(Test *)other {
319*67e74705SXin Li  use(self.strongProp.weakProp); // no-warning
320*67e74705SXin Li  use(other.strongProp.weakProp); // no-warning
321*67e74705SXin Li
322*67e74705SXin Li  use(self->ivar.weakProp); // no-warning
323*67e74705SXin Li  use(other->ivar.weakProp); // no-warning
324*67e74705SXin Li
325*67e74705SXin Li  use(self.strongProp->weakIvar); // no-warning
326*67e74705SXin Li  use(other.strongProp->weakIvar); // no-warning
327*67e74705SXin Li}
328*67e74705SXin Li@end
329*67e74705SXin Li
330*67e74705SXin Li@interface Base1
331*67e74705SXin Li@end
332*67e74705SXin Li@interface Sub1 : Base1
333*67e74705SXin Li@end
334*67e74705SXin Li@interface Sub1(cat)
335*67e74705SXin Li-(id)prop;
336*67e74705SXin Li@end
337*67e74705SXin Li
338*67e74705SXin Livoid test1(Sub1 *s) {
339*67e74705SXin Li  use([s prop]);
340*67e74705SXin Li  use([s prop]);
341*67e74705SXin Li}
342*67e74705SXin Li
343*67e74705SXin Li@interface Base1(cat)
344*67e74705SXin Li@property (weak) id prop;
345*67e74705SXin Li@end
346*67e74705SXin Li
347*67e74705SXin Livoid test2(Sub1 *s) {
348*67e74705SXin Li  // This does not warn because the "prop" in "Base1(cat)" was introduced
349*67e74705SXin Li  // after the method declaration and we don't find it as overridden.
350*67e74705SXin Li  // Always looking for overridden methods after the method declaration is expensive
351*67e74705SXin Li  // and it's not clear it is worth it currently.
352*67e74705SXin Li  use([s prop]);
353*67e74705SXin Li  use([s prop]);
354*67e74705SXin Li}
355*67e74705SXin Li
356*67e74705SXin Li
357*67e74705SXin Liclass Wrapper {
358*67e74705SXin Li  Test *a;
359*67e74705SXin Li
360*67e74705SXin Lipublic:
361*67e74705SXin Li  void fields() {
362*67e74705SXin Li    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*67e74705SXin Li    use(a.weakProp); // expected-note{{also accessed here}}
364*67e74705SXin Li  }
365*67e74705SXin Li
366*67e74705SXin Li  void distinctFromOther(Test *b, const Wrapper &w) {
367*67e74705SXin Li    use(a.weakProp); // no-warning
368*67e74705SXin Li    use(b.weakProp); // no-warning
369*67e74705SXin Li    use(w.a.weakProp); // no-warning
370*67e74705SXin Li  }
371*67e74705SXin Li
372*67e74705SXin Li  static void doubleLevelAccessField(const Wrapper &x, const Wrapper &y) {
373*67e74705SXin Li    use(x.a.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}
374*67e74705SXin Li    use(y.a.weakProp); // expected-note{{also accessed here}}
375*67e74705SXin Li  }
376*67e74705SXin Li};
377*67e74705SXin Li
378*67e74705SXin Li
379*67e74705SXin Li// -----------------------
380*67e74705SXin Li// False positives
381*67e74705SXin Li// -----------------------
382*67e74705SXin Li
383*67e74705SXin Li// Most of these would require flow-sensitive analysis to silence correctly.
384*67e74705SXin Li
385*67e74705SXin Livoid assignNil(Test *a) {
386*67e74705SXin Li  if (condition())
387*67e74705SXin Li    a.weakProp = nil; // expected-note{{also accessed here}}
388*67e74705SXin Li
389*67e74705SXin Li  use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
390*67e74705SXin Li}
391*67e74705SXin Li
392*67e74705SXin Livoid branch(Test *a) {
393*67e74705SXin Li  if (condition())
394*67e74705SXin Li    use(a.weakProp); // expected-warning{{weak property 'weakProp' is accessed multiple times}}
395*67e74705SXin Li  else
396*67e74705SXin Li    use(a.weakProp); // expected-note{{also accessed here}}
397*67e74705SXin Li}
398*67e74705SXin Li
399*67e74705SXin Livoid doubleLevelAccess(Test *a, Test *b) {
400*67e74705SXin Li  use(a.strongProp.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}
401*67e74705SXin Li  use(b.strongProp.weakProp); // expected-note{{also accessed here}}
402*67e74705SXin Li
403*67e74705SXin Li  use(a.weakProp.weakProp); // no-warning
404*67e74705SXin Li}
405*67e74705SXin Li
406*67e74705SXin Livoid doubleLevelAccessIvar(Test *a, Test *b) {
407*67e74705SXin Li  use(a->ivar.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}
408*67e74705SXin Li  use(b->ivar.weakProp); // expected-note{{also accessed here}}
409*67e74705SXin Li
410*67e74705SXin Li  use(a.strongProp.weakProp); // no-warning
411*67e74705SXin Li}
412*67e74705SXin Li
413*67e74705SXin Li// rdar://13942025
414*67e74705SXin Li@interface X
415*67e74705SXin Li@end
416*67e74705SXin Li
417*67e74705SXin Li@implementation X
418*67e74705SXin Li- (int) warningAboutWeakVariableInsideTypeof {
419*67e74705SXin Li    __typeof__(self) __weak weakSelf = self;
420*67e74705SXin Li    ^(){
421*67e74705SXin Li        __typeof__(weakSelf) blockSelf = weakSelf;
422*67e74705SXin Li        use(blockSelf);
423*67e74705SXin Li    }();
424*67e74705SXin Li    return sizeof(weakSelf);
425*67e74705SXin Li}
426*67e74705SXin Li@end
427*67e74705SXin Li
428*67e74705SXin Li// rdar://19053620
429*67e74705SXin Li@interface NSNull
430*67e74705SXin Li+ (NSNull *)null;
431*67e74705SXin Li@end
432*67e74705SXin Li
433*67e74705SXin Li@interface INTF @end
434*67e74705SXin Li
435*67e74705SXin Li@implementation INTF
436*67e74705SXin Li- (void) Meth : (id) data
437*67e74705SXin Li{
438*67e74705SXin Li  data = data ?: NSNull.null;
439*67e74705SXin Li}
440*67e74705SXin Li@end
441*67e74705SXin Li
442*67e74705SXin Li// This used to crash in WeakObjectProfileTy::getBaseInfo when getBase() was
443*67e74705SXin Li// called on an ObjCPropertyRefExpr object whose receiver was an interface.
444*67e74705SXin Li
445*67e74705SXin Li@class NSString;
446*67e74705SXin Li@interface NSBundle
447*67e74705SXin Li+(NSBundle *)foo;
448*67e74705SXin Li@property (class) NSBundle *foo2;
449*67e74705SXin Li@property NSString *prop;
450*67e74705SXin Li@property(weak) NSString *weakProp;
451*67e74705SXin Li@end
452*67e74705SXin Li
453*67e74705SXin Li@interface NSBundle2 : NSBundle
454*67e74705SXin Li@end
455*67e74705SXin Li
456*67e74705SXin Livoid foo() {
457*67e74705SXin Li  NSString * t = NSBundle.foo.prop;
458*67e74705SXin Li  use(NSBundle.foo.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}
459*67e74705SXin Li  use(NSBundle2.foo.weakProp); // expected-note{{also accessed here}}
460*67e74705SXin Li
461*67e74705SXin Li  NSString * t2 = NSBundle.foo2.prop;
462*67e74705SXin Li  use(NSBundle.foo2.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}
463*67e74705SXin Li  use(NSBundle2.foo2.weakProp); // expected-note{{also accessed here}}
464*67e74705SXin Li}
465