[clang-cl] Ignore /Wv and /Wv:17 flags
[llvm-project.git] / clang / test / Analysis / objc-for.m
bloba5b89d2619c6d67b43da22ec12a29ae3b6c196c5
1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.Loops,debug.ExprInspection -verify -analyzer-config eagerly-assume=false %s
3 void clang_analyzer_eval(int);
4 void clang_analyzer_warnIfReached(void);
6 #define nil ((id)0)
8 typedef unsigned long NSUInteger;
9 @protocol NSFastEnumeration
10 - (int)countByEnumeratingWithState:(void *)state objects:(id *)objects count:(unsigned)count;
11 - (void)protocolMethod;
12 @end
14 @interface NSObject
15 + (instancetype)testObject;
16 @end
18 @interface NSEnumerator <NSFastEnumeration>
19 @end
21 @interface NSArray : NSObject <NSFastEnumeration>
22 - (NSUInteger)count;
23 - (NSEnumerator *)objectEnumerator;
24 + (NSArray *)arrayWithObjects:(const id [])objects count:(NSUInteger)count;
25 @end
27 @interface NSDictionary : NSObject <NSFastEnumeration>
28 - (NSUInteger)count;
29 - (id)objectForKey:(id)key;
30 + (id)dictionaryWithObjects:(const id [])objects forKeys:(const id /* <NSCopying> */ [])keys count:(NSUInteger)count;
31 @end
33 @interface NSDictionary (SomeCategory)
34 - (void)categoryMethodOnNSDictionary;
35 - (id) allKeys;
36 @end
38 @interface NSMutableDictionary : NSDictionary
39 - (void)setObject:(id)obj forKey:(id)key;
40 @end
42 @interface NSMutableArray : NSArray
43 - (void)addObject:(id)obj;
44 @end
46 @interface NSSet : NSObject <NSFastEnumeration>
47 - (NSUInteger)count;
48 @end
50 @interface NSPointerArray : NSObject <NSFastEnumeration>
51 @end
53 @interface NSString : NSObject
54 @end
56 void test(void) {
57   id x;
58   for (x in [NSArray testObject])
59     clang_analyzer_eval(x != nil); // expected-warning{{TRUE}}
61   for (x in [NSMutableDictionary testObject])
62     clang_analyzer_eval(x != nil); // expected-warning{{TRUE}}
64   for (x in [NSSet testObject])
65     clang_analyzer_eval(x != nil); // expected-warning{{TRUE}}
67   for (x in [[NSArray testObject] objectEnumerator])
68     clang_analyzer_eval(x != nil); // expected-warning{{TRUE}}
70   for (x in [NSPointerArray testObject])
71     clang_analyzer_eval(x != nil); // expected-warning{{UNKNOWN}}
74 void testWithVarInFor(void) {
75   for (id x in [NSArray testObject])
76     clang_analyzer_eval(x != nil); // expected-warning{{TRUE}}
77   for (id x in [NSPointerArray testObject])
78     clang_analyzer_eval(x != nil); // expected-warning{{UNKNOWN}}
81 void testNonNil(id a, id b) {
82   clang_analyzer_eval(a != nil); // expected-warning{{UNKNOWN}}
83   for (id x in a)
84     clang_analyzer_eval(a != nil); // expected-warning{{TRUE}}
86   if (b != nil)
87     return;
88   for (id x in b)
89     *(volatile int *)0 = 1; // no-warning
90   clang_analyzer_eval(b != nil); // expected-warning{{FALSE}}
93 void collectionIsEmpty(NSMutableDictionary *D){
94   if ([D count] == 0) { // Count is zero.
95     NSString *s = 0;
96     for (NSString *key in D) {
97       s = key;       // Loop is never entered.
98     }
99     clang_analyzer_eval(s == 0); //expected-warning{{TRUE}}
100   }
103 void processCollection(NSMutableDictionary *D);
104 void collectionIsEmptyCollectionIsModified(NSMutableDictionary *D){
105   if ([D count] == 0) {      // Count is zero.
106     NSString *s = 0;
107     processCollection(D);  // However, the collection has changed.
108     for (NSString *key in D) {
109       s = key;       // Loop might be entered.
110     }
111     clang_analyzer_eval(s == 0); //expected-warning{{FALSE}} //expected-warning{{TRUE}}
112   }
115 int collectionIsEmptyNSSet(NSSet *S){
116   if ([S count] == 2) { // Count is non-zero.
117     int tapCounts[2];
118     int i = 0;
119     for (NSString *elem in S) {
120       tapCounts[i]= 1;       // Loop is entered.
121       i++;
122     }
123     return (tapCounts[0]); //no warning
124   }
125   return 0;
128 int collectionIsNotEmptyNSArray(NSArray *A) {
129   int count = [A count];
130   if (count > 0) {
131     int i;
132     int j = 0;
133     for (NSString *a in A) {
134       i = 1;
135       j++;
136     }
137     clang_analyzer_eval(i == 1); // expected-warning {{TRUE}}
138   }
139   return 0;
142 void onlySuppressExitAfterZeroIterations(NSMutableDictionary *D) {
143   if (D.count > 0) {
144     int *x;
145     int i = 0;
146     for (NSString *key in D) {
147       x = 0;
148       i++;
149     }
150     // Test that this is reachable.
151     int y = *x; // expected-warning {{Dereference of null pointer}}
152     y++;
153   }
156 void onlySuppressLoopExitAfterZeroIterations_WithContinue(NSMutableDictionary *D) {
157   if (D.count > 0) {
158     int *x;
159     int i = 0;
160     for (NSString *key in D) {
161       x = 0;
162       i++;
163       continue;
164     }
165     // Test that this is reachable.
166     int y = *x; // expected-warning {{Dereference of null pointer}}
167     y++;
168   }
171 int* getPtr(void);
172 void onlySuppressLoopExitAfterZeroIterations_WithBreak(NSMutableDictionary *D) {
173   if (D.count > 0) {
174     int *x;
175     int i;
176     for (NSString *key in D) {
177       x = 0;
178       break;
179       x = getPtr();
180       i++;
181     }
182     int y = *x; // expected-warning {{Dereference of null pointer}}
183     y++;
184   }
187 int consistencyBetweenLoopsWhenCountIsUnconstrained(NSMutableDictionary *D,
188                                                     int shouldUseCount) {
189   // Test with or without an initial count.
190   int count;
191   if (shouldUseCount)
192     count = [D count];
194   int i;
195   int j = 0;
196   for (NSString *key in D) {
197     i = 5;
198     j++;
199   }
200   for (NSString *key in D)  {
201     return i; // no-warning
202   }
203   return 0;
206 int consistencyBetweenLoopsWhenCountIsUnconstrained_dual(NSMutableDictionary *D,
207                                                          int shouldUseCount) {
208   int count;
209   if (shouldUseCount)
210     count = [D count];
212   int i = 8;
213   int j = 1;
214   for (NSString *key in D) {
215     i = 0;
216     j++;
217   }
218   for (NSString *key in D)  {
219     i = 5;
220     j++;
221   }
222   return 5/i;
225 int consistencyCountThenLoop(NSArray *array) {
226   if ([array count] == 0)
227     return 0;
229   int x;
230   for (id y in array)
231     x = 0;
232   return x; // no-warning
235 int consistencyLoopThenCount(NSArray *array) {
236   int x;
237   for (id y in array)
238     x = 0;
240   if ([array count] == 0)
241     return 0;
243   return x; // no-warning
246 void nonMutatingMethodsDoNotInvalidateCountDictionary(NSMutableDictionary *dict,
247                                                       NSMutableArray *other) {
248   if ([dict count])
249     return;
251   for (id key in dict)
252     clang_analyzer_eval(0); // no-warning
254   (void)[dict objectForKey:@""];
256   for (id key in dict)
257     clang_analyzer_eval(0); // no-warning
259   [dict categoryMethodOnNSDictionary];
261   for (id key in dict)
262     clang_analyzer_eval(0); // no-warning
264   [dict setObject:@"" forKey:@""];
266   for (id key in dict)
267     clang_analyzer_eval(0); // expected-warning{{FALSE}}
269   // Reset.
270   if ([dict count])
271     return;
273   for (id key in dict)
274     clang_analyzer_eval(0); // no-warning
276   [other addObject:dict];
278   for (id key in dict)
279     clang_analyzer_eval(0); // expected-warning{{FALSE}}
282 void nonMutatingMethodsDoNotInvalidateCountArray(NSMutableArray *array,
283                                                  NSMutableArray *other) {
284   if ([array count])
285     return;
287   for (id key in array)
288     clang_analyzer_eval(0); // no-warning
290   (void)[array objectEnumerator];
292   for (id key in array)
293     clang_analyzer_eval(0); // no-warning
295   [array addObject:@""];
297   for (id key in array)
298     clang_analyzer_eval(0); // expected-warning{{FALSE}}
300   // Reset.
301   if ([array count])
302     return;
304   for (id key in array)
305     clang_analyzer_eval(0); // no-warning
307   [other addObject:array];
309   for (id key in array)
310     clang_analyzer_eval(0); // expected-warning{{FALSE}}
313 void protocolMethods(NSMutableArray *array) {
314   if ([array count])
315     return;
317   for (id key in array)
318     clang_analyzer_eval(0); // no-warning
320   NSArray *immutableArray = array;
321   [immutableArray protocolMethod];
323   for (id key in array)
324     clang_analyzer_eval(0); // no-warning
326   [array protocolMethod];
328   for (id key in array)
329     clang_analyzer_eval(0); // expected-warning{{FALSE}}
332 NSArray *globalArray;
333 NSDictionary *globalDictionary;
334 void boxedArrayEscape(NSMutableArray *array) {
335   if ([array count])
336     return;
337   globalArray = @[array];
338   for (id key in array)
339     clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
341   if ([array count])
342     return;
343   globalDictionary = @{ @"array" : array };
344   for (id key in array)
345     clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
348 int not_reachable_on_iteration_through_nil(void) {
349   NSDictionary* d = nil;
350   for (NSString* s in [d allKeys])
351     clang_analyzer_warnIfReached(); // no-warning
352   return 0;