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