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);
8 typedef unsigned long NSUInteger;
9 @protocol NSFastEnumeration
10 - (int)countByEnumeratingWithState:(void *)state objects:(id *)objects count:(unsigned)count;
11 - (void)protocolMethod;
15 + (instancetype)testObject;
18 @interface NSEnumerator <NSFastEnumeration>
21 @interface NSArray : NSObject <NSFastEnumeration>
23 - (NSEnumerator *)objectEnumerator;
24 + (NSArray *)arrayWithObjects:(const id [])objects count:(NSUInteger)count;
27 @interface NSDictionary : NSObject <NSFastEnumeration>
29 - (id)objectForKey:(id)key;
30 + (id)dictionaryWithObjects:(const id [])objects forKeys:(const id /* <NSCopying> */ [])keys count:(NSUInteger)count;
33 @interface NSDictionary (SomeCategory)
34 - (void)categoryMethodOnNSDictionary;
38 @interface NSMutableDictionary : NSDictionary
39 - (void)setObject:(id)obj forKey:(id)key;
42 @interface NSMutableArray : NSArray
43 - (void)addObject:(id)obj;
46 @interface NSSet : NSObject <NSFastEnumeration>
50 @interface NSPointerArray : NSObject <NSFastEnumeration>
53 @interface NSString : NSObject
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}}
84 clang_analyzer_eval(a != nil); // expected-warning{{TRUE}}
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.
96 for (NSString *key in D) {
97 s = key; // Loop is never entered.
99 clang_analyzer_eval(s == 0); //expected-warning{{TRUE}}
103 void processCollection(NSMutableDictionary *D);
104 void collectionIsEmptyCollectionIsModified(NSMutableDictionary *D){
105 if ([D count] == 0) { // Count is zero.
107 processCollection(D); // However, the collection has changed.
108 for (NSString *key in D) {
109 s = key; // Loop might be entered.
111 clang_analyzer_eval(s == 0); //expected-warning{{FALSE}} //expected-warning{{TRUE}}
115 int collectionIsEmptyNSSet(NSSet *S){
116 if ([S count] == 2) { // Count is non-zero.
119 for (NSString *elem in S) {
120 tapCounts[i]= 1; // Loop is entered.
123 return (tapCounts[0]); //no warning
128 int collectionIsNotEmptyNSArray(NSArray *A) {
129 int count = [A count];
133 for (NSString *a in A) {
137 clang_analyzer_eval(i == 1); // expected-warning {{TRUE}}
142 void onlySuppressExitAfterZeroIterations(NSMutableDictionary *D) {
146 for (NSString *key in D) {
150 // Test that this is reachable.
151 int y = *x; // expected-warning {{Dereference of null pointer}}
156 void onlySuppressLoopExitAfterZeroIterations_WithContinue(NSMutableDictionary *D) {
160 for (NSString *key in D) {
165 // Test that this is reachable.
166 int y = *x; // expected-warning {{Dereference of null pointer}}
172 void onlySuppressLoopExitAfterZeroIterations_WithBreak(NSMutableDictionary *D) {
176 for (NSString *key in D) {
182 int y = *x; // expected-warning {{Dereference of null pointer}}
187 int consistencyBetweenLoopsWhenCountIsUnconstrained(NSMutableDictionary *D,
188 int shouldUseCount) {
189 // Test with or without an initial count.
196 for (NSString *key in D) {
200 for (NSString *key in D) {
201 return i; // no-warning
206 int consistencyBetweenLoopsWhenCountIsUnconstrained_dual(NSMutableDictionary *D,
207 int shouldUseCount) {
214 for (NSString *key in D) {
218 for (NSString *key in D) {
225 int consistencyCountThenLoop(NSArray *array) {
226 if ([array count] == 0)
232 return x; // no-warning
235 int consistencyLoopThenCount(NSArray *array) {
240 if ([array count] == 0)
243 return x; // no-warning
246 void nonMutatingMethodsDoNotInvalidateCountDictionary(NSMutableDictionary *dict,
247 NSMutableArray *other) {
252 clang_analyzer_eval(0); // no-warning
254 (void)[dict objectForKey:@""];
257 clang_analyzer_eval(0); // no-warning
259 [dict categoryMethodOnNSDictionary];
262 clang_analyzer_eval(0); // no-warning
264 [dict setObject:@"" forKey:@""];
267 clang_analyzer_eval(0); // expected-warning{{FALSE}}
274 clang_analyzer_eval(0); // no-warning
276 [other addObject:dict];
279 clang_analyzer_eval(0); // expected-warning{{FALSE}}
282 void nonMutatingMethodsDoNotInvalidateCountArray(NSMutableArray *array,
283 NSMutableArray *other) {
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}}
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) {
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) {
337 globalArray = @[array];
338 for (id key in array)
339 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
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