xref: /minix3/external/bsd/llvm/dist/clang/test/Analysis/objc-for.m (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1f4a2713aSLionel Sambuc// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.Loops,debug.ExprInspection -verify %s
2f4a2713aSLionel Sambuc
3f4a2713aSLionel Sambucvoid clang_analyzer_eval(int);
4f4a2713aSLionel Sambuc
5f4a2713aSLionel Sambuc#define nil ((id)0)
6f4a2713aSLionel Sambuc
7f4a2713aSLionel Sambuctypedef unsigned long NSUInteger;
8f4a2713aSLionel Sambuc@protocol NSFastEnumeration
9f4a2713aSLionel Sambuc- (int)countByEnumeratingWithState:(void *)state objects:(id *)objects count:(unsigned)count;
10f4a2713aSLionel Sambuc- (void)protocolMethod;
11f4a2713aSLionel Sambuc@end
12f4a2713aSLionel Sambuc
13f4a2713aSLionel Sambuc@interface NSObject
14f4a2713aSLionel Sambuc+ (instancetype)testObject;
15f4a2713aSLionel Sambuc@end
16f4a2713aSLionel Sambuc
17f4a2713aSLionel Sambuc@interface NSEnumerator <NSFastEnumeration>
18f4a2713aSLionel Sambuc@end
19f4a2713aSLionel Sambuc
20f4a2713aSLionel Sambuc@interface NSArray : NSObject <NSFastEnumeration>
21f4a2713aSLionel Sambuc- (NSUInteger)count;
22f4a2713aSLionel Sambuc- (NSEnumerator *)objectEnumerator;
23f4a2713aSLionel Sambuc@end
24f4a2713aSLionel Sambuc
25f4a2713aSLionel Sambuc@interface NSDictionary : NSObject <NSFastEnumeration>
26f4a2713aSLionel Sambuc- (NSUInteger)count;
27f4a2713aSLionel Sambuc- (id)objectForKey:(id)key;
28f4a2713aSLionel Sambuc@end
29f4a2713aSLionel Sambuc
30f4a2713aSLionel Sambuc@interface NSDictionary (SomeCategory)
31f4a2713aSLionel Sambuc- (void)categoryMethodOnNSDictionary;
32f4a2713aSLionel Sambuc@end
33f4a2713aSLionel Sambuc
34f4a2713aSLionel Sambuc@interface NSMutableDictionary : NSDictionary
35f4a2713aSLionel Sambuc- (void)setObject:(id)obj forKey:(id)key;
36f4a2713aSLionel Sambuc@end
37f4a2713aSLionel Sambuc
38f4a2713aSLionel Sambuc@interface NSMutableArray : NSArray
39f4a2713aSLionel Sambuc- (void)addObject:(id)obj;
40f4a2713aSLionel Sambuc@end
41f4a2713aSLionel Sambuc
42f4a2713aSLionel Sambuc@interface NSSet : NSObject <NSFastEnumeration>
43f4a2713aSLionel Sambuc- (NSUInteger)count;
44f4a2713aSLionel Sambuc@end
45f4a2713aSLionel Sambuc
46f4a2713aSLionel Sambuc@interface NSPointerArray : NSObject <NSFastEnumeration>
47f4a2713aSLionel Sambuc@end
48f4a2713aSLionel Sambuc
49f4a2713aSLionel Sambuc@interface NSString : NSObject
50f4a2713aSLionel Sambuc@end
51f4a2713aSLionel Sambuc
52f4a2713aSLionel Sambucvoid test() {
53f4a2713aSLionel Sambuc  id x;
54f4a2713aSLionel Sambuc  for (x in [NSArray testObject])
55f4a2713aSLionel Sambuc    clang_analyzer_eval(x != nil); // expected-warning{{TRUE}}
56f4a2713aSLionel Sambuc
57f4a2713aSLionel Sambuc  for (x in [NSMutableDictionary testObject])
58f4a2713aSLionel Sambuc    clang_analyzer_eval(x != nil); // expected-warning{{TRUE}}
59f4a2713aSLionel Sambuc
60f4a2713aSLionel Sambuc  for (x in [NSSet testObject])
61f4a2713aSLionel Sambuc    clang_analyzer_eval(x != nil); // expected-warning{{TRUE}}
62f4a2713aSLionel Sambuc
63f4a2713aSLionel Sambuc  for (x in [[NSArray testObject] objectEnumerator])
64f4a2713aSLionel Sambuc    clang_analyzer_eval(x != nil); // expected-warning{{TRUE}}
65f4a2713aSLionel Sambuc
66f4a2713aSLionel Sambuc  for (x in [NSPointerArray testObject])
67f4a2713aSLionel Sambuc    clang_analyzer_eval(x != nil); // expected-warning{{UNKNOWN}}
68f4a2713aSLionel Sambuc}
69f4a2713aSLionel Sambuc
70f4a2713aSLionel Sambucvoid testWithVarInFor() {
71f4a2713aSLionel Sambuc  for (id x in [NSArray testObject])
72f4a2713aSLionel Sambuc    clang_analyzer_eval(x != nil); // expected-warning{{TRUE}}
73f4a2713aSLionel Sambuc  for (id x in [NSPointerArray testObject])
74f4a2713aSLionel Sambuc    clang_analyzer_eval(x != nil); // expected-warning{{UNKNOWN}}
75f4a2713aSLionel Sambuc}
76f4a2713aSLionel Sambuc
77f4a2713aSLionel Sambucvoid testNonNil(id a, id b) {
78f4a2713aSLionel Sambuc  clang_analyzer_eval(a != nil); // expected-warning{{UNKNOWN}}
79f4a2713aSLionel Sambuc  for (id x in a)
80f4a2713aSLionel Sambuc    clang_analyzer_eval(a != nil); // expected-warning{{TRUE}}
81f4a2713aSLionel Sambuc
82f4a2713aSLionel Sambuc  if (b != nil)
83f4a2713aSLionel Sambuc    return;
84f4a2713aSLionel Sambuc  for (id x in b)
85f4a2713aSLionel Sambuc    *(volatile int *)0 = 1; // no-warning
86f4a2713aSLionel Sambuc  clang_analyzer_eval(b != nil); // expected-warning{{FALSE}}
87f4a2713aSLionel Sambuc}
88f4a2713aSLionel Sambuc
89f4a2713aSLionel Sambucvoid collectionIsEmpty(NSMutableDictionary *D){
90f4a2713aSLionel Sambuc  if ([D count] == 0) { // Count is zero.
91f4a2713aSLionel Sambuc    NSString *s = 0;
92f4a2713aSLionel Sambuc    for (NSString *key in D) {
93f4a2713aSLionel Sambuc      s = key;       // Loop is never entered.
94f4a2713aSLionel Sambuc    }
95f4a2713aSLionel Sambuc    clang_analyzer_eval(s == 0); //expected-warning{{TRUE}}
96f4a2713aSLionel Sambuc  }
97f4a2713aSLionel Sambuc}
98f4a2713aSLionel Sambuc
99f4a2713aSLionel Sambucvoid processCollection(NSMutableDictionary *D);
100f4a2713aSLionel Sambucvoid collectionIsEmptyCollectionIsModified(NSMutableDictionary *D){
101f4a2713aSLionel Sambuc  if ([D count] == 0) {      // Count is zero.
102f4a2713aSLionel Sambuc    NSString *s = 0;
103f4a2713aSLionel Sambuc    processCollection(D);  // However, the collection has changed.
104f4a2713aSLionel Sambuc    for (NSString *key in D) {
105f4a2713aSLionel Sambuc      s = key;       // Loop might be entered.
106f4a2713aSLionel Sambuc    }
107f4a2713aSLionel Sambuc    clang_analyzer_eval(s == 0); //expected-warning{{FALSE}} //expected-warning{{TRUE}}
108f4a2713aSLionel Sambuc  }
109f4a2713aSLionel Sambuc}
110f4a2713aSLionel Sambuc
111f4a2713aSLionel Sambucint collectionIsEmptyNSSet(NSSet *S){
112*0a6a1f1dSLionel Sambuc  if ([S count] == 2) { // Count is non-zero.
113f4a2713aSLionel Sambuc    int tapCounts[2];
114f4a2713aSLionel Sambuc    int i = 0;
115f4a2713aSLionel Sambuc    for (NSString *elem in S) {
116f4a2713aSLionel Sambuc      tapCounts[i]= 1;       // Loop is entered.
117f4a2713aSLionel Sambuc      i++;
118f4a2713aSLionel Sambuc    }
119f4a2713aSLionel Sambuc    return (tapCounts[0]); //no warning
120f4a2713aSLionel Sambuc  }
121f4a2713aSLionel Sambuc  return 0;
122f4a2713aSLionel Sambuc}
123f4a2713aSLionel Sambuc
124f4a2713aSLionel Sambucint collectionIsNotEmptyNSArray(NSArray *A) {
125f4a2713aSLionel Sambuc  int count = [A count];
126f4a2713aSLionel Sambuc  if (count > 0) {
127f4a2713aSLionel Sambuc    int i;
128f4a2713aSLionel Sambuc    int j;
129f4a2713aSLionel Sambuc    for (NSString *a in A) {
130f4a2713aSLionel Sambuc      i = 1;
131f4a2713aSLionel Sambuc      j++;
132f4a2713aSLionel Sambuc    }
133f4a2713aSLionel Sambuc    clang_analyzer_eval(i == 1); // expected-warning {{TRUE}}
134f4a2713aSLionel Sambuc  }
135f4a2713aSLionel Sambuc  return 0;
136f4a2713aSLionel Sambuc}
137f4a2713aSLionel Sambuc
138f4a2713aSLionel Sambucvoid onlySuppressExitAfterZeroIterations(NSMutableDictionary *D) {
139f4a2713aSLionel Sambuc  if (D.count > 0) {
140f4a2713aSLionel Sambuc    int *x;
141f4a2713aSLionel Sambuc    int i;
142f4a2713aSLionel Sambuc    for (NSString *key in D) {
143f4a2713aSLionel Sambuc      x = 0;
144f4a2713aSLionel Sambuc      i++;
145f4a2713aSLionel Sambuc    }
146f4a2713aSLionel Sambuc    // Test that this is reachable.
147f4a2713aSLionel Sambuc    int y = *x; // expected-warning {{Dereference of null pointer}}
148f4a2713aSLionel Sambuc    y++;
149f4a2713aSLionel Sambuc  }
150f4a2713aSLionel Sambuc}
151f4a2713aSLionel Sambuc
152f4a2713aSLionel Sambucvoid onlySuppressLoopExitAfterZeroIterations_WithContinue(NSMutableDictionary *D) {
153f4a2713aSLionel Sambuc  if (D.count > 0) {
154f4a2713aSLionel Sambuc    int *x;
155f4a2713aSLionel Sambuc    int i;
156f4a2713aSLionel Sambuc    for (NSString *key in D) {
157f4a2713aSLionel Sambuc      x = 0;
158f4a2713aSLionel Sambuc      i++;
159f4a2713aSLionel Sambuc      continue;
160f4a2713aSLionel Sambuc    }
161f4a2713aSLionel Sambuc    // Test that this is reachable.
162f4a2713aSLionel Sambuc    int y = *x; // expected-warning {{Dereference of null pointer}}
163f4a2713aSLionel Sambuc    y++;
164f4a2713aSLionel Sambuc  }
165f4a2713aSLionel Sambuc}
166f4a2713aSLionel Sambuc
167f4a2713aSLionel Sambucint* getPtr();
168f4a2713aSLionel Sambucvoid onlySuppressLoopExitAfterZeroIterations_WithBreak(NSMutableDictionary *D) {
169f4a2713aSLionel Sambuc  if (D.count > 0) {
170f4a2713aSLionel Sambuc    int *x;
171f4a2713aSLionel Sambuc    int i;
172f4a2713aSLionel Sambuc    for (NSString *key in D) {
173f4a2713aSLionel Sambuc      x = 0;
174f4a2713aSLionel Sambuc      break;
175f4a2713aSLionel Sambuc      x = getPtr();
176f4a2713aSLionel Sambuc      i++;
177f4a2713aSLionel Sambuc    }
178f4a2713aSLionel Sambuc    int y = *x; // expected-warning {{Dereference of null pointer}}
179f4a2713aSLionel Sambuc    y++;
180f4a2713aSLionel Sambuc  }
181f4a2713aSLionel Sambuc}
182f4a2713aSLionel Sambuc
183f4a2713aSLionel Sambucint consistencyBetweenLoopsWhenCountIsUnconstrained(NSMutableDictionary *D,
184f4a2713aSLionel Sambuc                                                    int shouldUseCount) {
185f4a2713aSLionel Sambuc  // Test with or without an initial count.
186f4a2713aSLionel Sambuc  int count;
187f4a2713aSLionel Sambuc  if (shouldUseCount)
188f4a2713aSLionel Sambuc    count = [D count];
189f4a2713aSLionel Sambuc
190f4a2713aSLionel Sambuc  int i;
191f4a2713aSLionel Sambuc  int j = 0;
192f4a2713aSLionel Sambuc  for (NSString *key in D) {
193f4a2713aSLionel Sambuc    i = 5;
194f4a2713aSLionel Sambuc    j++;
195f4a2713aSLionel Sambuc  }
196f4a2713aSLionel Sambuc  for (NSString *key in D)  {
197f4a2713aSLionel Sambuc    return i; // no-warning
198f4a2713aSLionel Sambuc  }
199f4a2713aSLionel Sambuc  return 0;
200f4a2713aSLionel Sambuc}
201f4a2713aSLionel Sambuc
202f4a2713aSLionel Sambucint consistencyBetweenLoopsWhenCountIsUnconstrained_dual(NSMutableDictionary *D,
203f4a2713aSLionel Sambuc                                                         int shouldUseCount) {
204f4a2713aSLionel Sambuc  int count;
205f4a2713aSLionel Sambuc  if (shouldUseCount)
206f4a2713aSLionel Sambuc    count = [D count];
207f4a2713aSLionel Sambuc
208f4a2713aSLionel Sambuc  int i = 8;
209f4a2713aSLionel Sambuc  int j = 1;
210f4a2713aSLionel Sambuc  for (NSString *key in D) {
211f4a2713aSLionel Sambuc    i = 0;
212f4a2713aSLionel Sambuc    j++;
213f4a2713aSLionel Sambuc  }
214f4a2713aSLionel Sambuc  for (NSString *key in D)  {
215f4a2713aSLionel Sambuc    i = 5;
216f4a2713aSLionel Sambuc    j++;
217f4a2713aSLionel Sambuc  }
218f4a2713aSLionel Sambuc  return 5/i;
219f4a2713aSLionel Sambuc}
220f4a2713aSLionel Sambuc
221f4a2713aSLionel Sambucint consistencyCountThenLoop(NSArray *array) {
222f4a2713aSLionel Sambuc  if ([array count] == 0)
223f4a2713aSLionel Sambuc    return 0;
224f4a2713aSLionel Sambuc
225f4a2713aSLionel Sambuc  int x;
226f4a2713aSLionel Sambuc  for (id y in array)
227f4a2713aSLionel Sambuc    x = 0;
228f4a2713aSLionel Sambuc  return x; // no-warning
229f4a2713aSLionel Sambuc}
230f4a2713aSLionel Sambuc
231f4a2713aSLionel Sambucint consistencyLoopThenCount(NSArray *array) {
232f4a2713aSLionel Sambuc  int x;
233f4a2713aSLionel Sambuc  for (id y in array)
234f4a2713aSLionel Sambuc    x = 0;
235f4a2713aSLionel Sambuc
236f4a2713aSLionel Sambuc  if ([array count] == 0)
237f4a2713aSLionel Sambuc    return 0;
238f4a2713aSLionel Sambuc
239f4a2713aSLionel Sambuc  return x; // no-warning
240f4a2713aSLionel Sambuc}
241f4a2713aSLionel Sambuc
242f4a2713aSLionel Sambucvoid nonMutatingMethodsDoNotInvalidateCountDictionary(NSMutableDictionary *dict,
243f4a2713aSLionel Sambuc                                                      NSMutableArray *other) {
244f4a2713aSLionel Sambuc  if ([dict count])
245f4a2713aSLionel Sambuc    return;
246f4a2713aSLionel Sambuc
247f4a2713aSLionel Sambuc  for (id key in dict)
248f4a2713aSLionel Sambuc    clang_analyzer_eval(0); // no-warning
249f4a2713aSLionel Sambuc
250f4a2713aSLionel Sambuc  (void)[dict objectForKey:@""];
251f4a2713aSLionel Sambuc
252f4a2713aSLionel Sambuc  for (id key in dict)
253f4a2713aSLionel Sambuc    clang_analyzer_eval(0); // no-warning
254f4a2713aSLionel Sambuc
255f4a2713aSLionel Sambuc  [dict categoryMethodOnNSDictionary];
256f4a2713aSLionel Sambuc
257f4a2713aSLionel Sambuc  for (id key in dict)
258f4a2713aSLionel Sambuc    clang_analyzer_eval(0); // no-warning
259f4a2713aSLionel Sambuc
260f4a2713aSLionel Sambuc  [dict setObject:@"" forKey:@""];
261f4a2713aSLionel Sambuc
262f4a2713aSLionel Sambuc  for (id key in dict)
263f4a2713aSLionel Sambuc    clang_analyzer_eval(0); // expected-warning{{FALSE}}
264f4a2713aSLionel Sambuc
265f4a2713aSLionel Sambuc  // Reset.
266f4a2713aSLionel Sambuc  if ([dict count])
267f4a2713aSLionel Sambuc    return;
268f4a2713aSLionel Sambuc
269f4a2713aSLionel Sambuc  for (id key in dict)
270f4a2713aSLionel Sambuc    clang_analyzer_eval(0); // no-warning
271f4a2713aSLionel Sambuc
272f4a2713aSLionel Sambuc  [other addObject:dict];
273f4a2713aSLionel Sambuc
274f4a2713aSLionel Sambuc  for (id key in dict)
275f4a2713aSLionel Sambuc    clang_analyzer_eval(0); // expected-warning{{FALSE}}
276f4a2713aSLionel Sambuc}
277f4a2713aSLionel Sambuc
278f4a2713aSLionel Sambucvoid nonMutatingMethodsDoNotInvalidateCountArray(NSMutableArray *array,
279f4a2713aSLionel Sambuc                                                 NSMutableArray *other) {
280f4a2713aSLionel Sambuc  if ([array count])
281f4a2713aSLionel Sambuc    return;
282f4a2713aSLionel Sambuc
283f4a2713aSLionel Sambuc  for (id key in array)
284f4a2713aSLionel Sambuc    clang_analyzer_eval(0); // no-warning
285f4a2713aSLionel Sambuc
286f4a2713aSLionel Sambuc  (void)[array objectEnumerator];
287f4a2713aSLionel Sambuc
288f4a2713aSLionel Sambuc  for (id key in array)
289f4a2713aSLionel Sambuc    clang_analyzer_eval(0); // no-warning
290f4a2713aSLionel Sambuc
291f4a2713aSLionel Sambuc  [array addObject:@""];
292f4a2713aSLionel Sambuc
293f4a2713aSLionel Sambuc  for (id key in array)
294f4a2713aSLionel Sambuc    clang_analyzer_eval(0); // expected-warning{{FALSE}}
295f4a2713aSLionel Sambuc
296f4a2713aSLionel Sambuc  // Reset.
297f4a2713aSLionel Sambuc  if ([array count])
298f4a2713aSLionel Sambuc    return;
299f4a2713aSLionel Sambuc
300f4a2713aSLionel Sambuc  for (id key in array)
301f4a2713aSLionel Sambuc    clang_analyzer_eval(0); // no-warning
302f4a2713aSLionel Sambuc
303f4a2713aSLionel Sambuc  [other addObject:array];
304f4a2713aSLionel Sambuc
305f4a2713aSLionel Sambuc  for (id key in array)
306f4a2713aSLionel Sambuc    clang_analyzer_eval(0); // expected-warning{{FALSE}}
307f4a2713aSLionel Sambuc}
308f4a2713aSLionel Sambuc
309f4a2713aSLionel Sambucvoid protocolMethods(NSMutableArray *array) {
310f4a2713aSLionel Sambuc  if ([array count])
311f4a2713aSLionel Sambuc    return;
312f4a2713aSLionel Sambuc
313f4a2713aSLionel Sambuc  for (id key in array)
314f4a2713aSLionel Sambuc    clang_analyzer_eval(0); // no-warning
315f4a2713aSLionel Sambuc
316f4a2713aSLionel Sambuc  NSArray *immutableArray = array;
317f4a2713aSLionel Sambuc  [immutableArray protocolMethod];
318f4a2713aSLionel Sambuc
319f4a2713aSLionel Sambuc  for (id key in array)
320f4a2713aSLionel Sambuc    clang_analyzer_eval(0); // no-warning
321f4a2713aSLionel Sambuc
322f4a2713aSLionel Sambuc  [array protocolMethod];
323f4a2713aSLionel Sambuc
324f4a2713aSLionel Sambuc  for (id key in array)
325f4a2713aSLionel Sambuc    clang_analyzer_eval(0); // expected-warning{{FALSE}}
326f4a2713aSLionel Sambuc}
327