[ELF] Avoid make in elf::writeARMCmseImportLib
[llvm-project.git] / clang / test / Analysis / NSContainers.m
blobceeb9ffbf2c8984568895808d416b845d13074f6
1 // RUN: %clang_analyze_cc1 -Wno-objc-literal-conversion -Wno-objc-root-class -fobjc-arc \
2 // RUN:   -analyzer-checker=core,osx.cocoa,nullability \
3 // RUN:   -analyzer-config eagerly-assume=false \
4 // RUN:   -analyzer-checker=debug.ExprInspection -verify %s
6 void clang_analyzer_eval(int);
8 #define nil ((id)0)
10 typedef unsigned long NSUInteger;
11 typedef signed char BOOL;
12 typedef struct _NSZone NSZone;
13 @class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
14 @protocol NSObject
15 @end
16 @protocol NSCopying
17 - (id)copyWithZone:(NSZone *)zone;
18 @end
19 @protocol NSMutableCopying
20 - (id)mutableCopyWithZone:(NSZone *)zone;
21 @end
22 @protocol NSCoding
23 - (void)encodeWithCoder:(NSCoder *)aCoder;
24 @end
25 @protocol NSSecureCoding <NSCoding>
26 @required
27 + (BOOL)supportsSecureCoding;
28 @end
29 @interface NSObject <NSObject> {}
30 - (id)init;
31 + (id)alloc;
33 - (id)mutableCopy;
34 @end
36 typedef struct {
37     unsigned long state;
38     id __unsafe_unretained _Nullable * _Nullable itemsPtr;
39     unsigned long * _Nullable mutationsPtr;
40     unsigned long extra[5];
41 } NSFastEnumerationState;
42 @protocol NSFastEnumeration
43 - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id __unsafe_unretained _Nullable [_Nonnull])buffer count:(NSUInteger)len;
44 @end
46 @interface NSArray : NSObject <NSCopying, NSMutableCopying, NSSecureCoding, NSFastEnumeration>
47 - (NSUInteger)count;
48 - (id)objectAtIndex:(NSUInteger)index;
49 @end
51 @interface NSArray (NSExtendedArray)
52 - (NSArray *)arrayByAddingObject:(id)anObject;
53 - (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)idx __attribute__((availability(macosx,introduced=10.8)));
54 @end
56 @interface NSArray (NSArrayCreation)
57 + (instancetype)arrayWithObjects:(const id [])objects count:(NSUInteger)cnt;
58 @end
60 @interface NSMutableArray : NSArray
62 - (void)addObject:(id)anObject;
63 - (void)insertObject:(id)anObject atIndex:(NSUInteger)index;
64 - (void)removeLastObject;
65 - (void)removeObjectAtIndex:(NSUInteger)index;
66 - (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject;
68 @end
70 @interface NSDictionary : NSObject <NSCopying, NSMutableCopying, NSSecureCoding, NSFastEnumeration>
72 - (NSUInteger)count;
73 - (id)objectForKey:(id)aKey;
74 - (NSEnumerator *)keyEnumerator;
76 @end
78 @interface NSDictionary (NSDictionaryCreation)
80 + (id)dictionary;
81 + (id)dictionaryWithObject:(id)object forKey:(id <NSCopying>)key;
82 + (instancetype)dictionaryWithObjects:(const id [])objects forKeys:(const id <NSCopying> [])keys count:(NSUInteger)cnt;
84 @end
86 @interface NSMutableDictionary : NSDictionary
88 - (void)removeObjectForKey:(id)aKey;
89 - (void)setObject:(id)anObject forKey:(id <NSCopying>)aKey;
91 @end
93 @interface NSMutableDictionary (NSExtendedMutableDictionary)
95 - (void)addEntriesFromDictionary:(NSDictionary *)otherDictionary;
96 - (void)removeAllObjects;
97 - (void)removeObjectsForKeys:(NSArray *)keyArray;
98 - (void)setDictionary:(NSDictionary *)otherDictionary;
99 - (void)setObject:(id)obj forKeyedSubscript:(id <NSCopying>)key __attribute__((availability(macosx,introduced=10.8)));
101 @end
103 @interface NSOrderedSet : NSObject <NSFastEnumeration>
104 @end
105 @interface NSOrderedSet (NSOrderedSetCreation)
106 - (NSUInteger)count;
107 @end
109 @interface NSString : NSObject <NSCopying, NSMutableCopying, NSSecureCoding>
111 @end
113 @interface NSNull : NSObject <NSCopying, NSSecureCoding>
114 + (NSNull *)null;
115 @end
117 // NSMutableArray API
118 void testNilArgNSMutableArray1(void) {
119   NSMutableArray *marray = [[NSMutableArray alloc] init];
120   [marray addObject:0]; // expected-warning {{Argument to 'NSMutableArray' method 'addObject:' cannot be nil}}
123 void testNilArgNSMutableArray2(void) {
124   NSMutableArray *marray = [[NSMutableArray alloc] init];
125   [marray insertObject:0 atIndex:1]; // expected-warning {{Argument to 'NSMutableArray' method 'insertObject:atIndex:' cannot be nil}}
128 void testNilArgNSMutableArray3(void) {
129   NSMutableArray *marray = [[NSMutableArray alloc] init];
130   [marray replaceObjectAtIndex:1 withObject:0]; // expected-warning {{Argument to 'NSMutableArray' method 'replaceObjectAtIndex:withObject:' cannot be nil}}
133 void testNilArgNSMutableArray4(void) {
134   NSMutableArray *marray = [[NSMutableArray alloc] init];
135   [marray setObject:0 atIndexedSubscript:1]; // expected-warning {{Argument to 'NSMutableArray' method 'setObject:atIndexedSubscript:' cannot be nil}}
138 void testNilArgNSMutableArray5(void) {
139   NSMutableArray *marray = [[NSMutableArray alloc] init];
140   marray[1] = 0; // expected-warning {{Array element cannot be nil}}
143 // NSArray API
144 void testNilArgNSArray1(void) {
145   NSArray *array = [[NSArray alloc] init];
146   NSArray *copyArray = [array arrayByAddingObject:0]; // expected-warning {{Argument to 'NSArray' method 'arrayByAddingObject:' cannot be nil}}
149 // NSMutableDictionary and NSDictionary APIs.
150 void testNilArgNSMutableDictionary1(NSMutableDictionary *d, NSString* key) {
151   [d setObject:0 forKey:key]; // expected-warning {{Value argument to 'setObject:forKey:' cannot be nil}}
154 void testNilArgNSMutableDictionary2(NSMutableDictionary *d, NSObject *obj) {
155   [d setObject:obj forKey:0]; // expected-warning {{Key argument to 'setObject:forKey:' cannot be nil}}
158 void testNilArgNSMutableDictionary3(NSMutableDictionary *d) {
159   [d removeObjectForKey:0]; // expected-warning {{Value argument to 'removeObjectForKey:' cannot be nil}}
162 void testNilArgNSMutableDictionary5(NSMutableDictionary *d, NSString* key) {
163   d[key] = 0; // no-warning - removing the mapping for the given key
165 void testNilArgNSMutableDictionary6(NSMutableDictionary *d, NSString *key) {
166   if (key)
167     ;
168   d[key] = 0; // expected-warning {{'NSMutableDictionary' key cannot be nil}}
171 NSDictionary *testNilArgNSDictionary1(NSString* key) {
172   return [NSDictionary dictionaryWithObject:0 forKey:key]; // expected-warning {{Value argument to 'dictionaryWithObject:forKey:' cannot be nil}}
174 NSDictionary *testNilArgNSDictionary2(NSObject *obj) {
175   return [NSDictionary dictionaryWithObject:obj forKey:0]; // expected-warning {{Key argument to 'dictionaryWithObject:forKey:' cannot be nil}}
178 id testCreateDictionaryLiteralKey(id value, id nilKey) {
179   if (nilKey)
180     ;
181   return @{@"abc":value, nilKey:@"abc"}; // expected-warning {{Dictionary key cannot be nil}}
184 id testCreateDictionaryLiteralValue(id nilValue) {
185   if (nilValue)
186     ;
187   return @{@"abc":nilValue}; // expected-warning {{Dictionary value cannot be nil}}
190 id testCreateDictionaryLiteral(id nilValue, id nilKey) {
191   if (nilValue)
192     ;
193   if (nilKey)
194     ;
195   return @{@"abc":nilValue, nilKey:@"abc"}; // expected-warning {{Dictionary key cannot be nil}}
196                                             // expected-warning@-1 {{Dictionary value cannot be nil}}
199 id testCreateArrayLiteral(id myNil) {
200   if (myNil)
201     ;
202   return @[ @"a", myNil, @"c" ]; // expected-warning {{Array element cannot be nil}}
205 // Test inline defensive checks suppression.
206 void idc(id x) {
207   if (x)
208     ;
210 void testIDC(NSMutableDictionary *d, NSString *key) {
211   idc(key);
212   d[key] = @"abc"; // no-warning
215 @interface Foo {
216 @public
217   int x;
219 - (int *)getPtr;
220 - (int)getInt;
221 - (NSMutableDictionary *)getDictPtr;
222 @property (retain, readonly, nonatomic) Foo* data;
223 - (NSString*) stringForKeyFE: (id<NSCopying>)key;
224 @end
226 void idc2(id x) {
227         if (!x)
228                 return;
230 Foo *retNil(void) {
231   return 0;
234 void testIDC2(Foo *obj) {
235         idc2(obj);
236         *[obj getPtr] = 1; // no-warning
239 int testIDC3(Foo *obj) {
240         idc2(obj);
241   return 1/[obj getInt];
244 void testNilReceiverIDC(Foo *obj, NSString *key) {
245         NSMutableDictionary *D = [obj getDictPtr];
246   idc(D);
247   D[key] = @"abc"; // no-warning
250 void testNilReceiverRetNil2(NSMutableDictionary *D, Foo *FooPtrIn, id value) {
251   NSString* const kKeyIdentifier = @"key";
252         Foo *FooPtr = retNil();
253   NSString *key = [[FooPtr data] stringForKeyFE: kKeyIdentifier];
254   // key is nil because FooPtr is nil. However, FooPtr is set to nil inside an
255   // inlined function, so this error report should be suppressed.
256   [D setObject: value forKey: key]; // no-warning
259 void testAssumeNSNullNullReturnsNonNil(NSMutableDictionary *Table, id Object,
260                                       id InValue) {
261   id Value = Object ? [Table objectForKey:Object] : [NSNull null];
262   if (!Value) {
263     Value = InValue;
264     [Table setObject:Value forKey:Object]; // no warning
265   }
268 void testCollectionIsNotEmptyWhenCountIsGreaterThanZero(NSMutableDictionary *D){
269   if ([D count] > 0) { // Count is greater than zero.
270     NSString *s = 0;
271     for (NSString *key in D) {
272       s = key;       // Loop is always entered.
273     }
274     [D removeObjectForKey:s]; // no warning
275   }
278 void testCountAwareNSOrderedSet(NSOrderedSet *containers, int *validptr) {
279         int *x = 0;
280   NSUInteger containerCount = [containers count];
281   if (containerCount > 0)    
282                 x = validptr;
283         for (id c in containers) {
284                 *x = 1; // no warning
285         }
288 void testLiteralsNonNil(void) {
289   clang_analyzer_eval(!!@[]); // expected-warning{{TRUE}}
290   clang_analyzer_eval(!!@{}); // expected-warning{{TRUE}}
293 @interface NSMutableArray (MySafeAdd)
294 - (void)addObject:(id)obj safe:(BOOL)safe;
295 @end
297 void testArrayCategory(NSMutableArray *arr) {
298   [arr addObject:0 safe:1]; // no-warning
301 @interface MyView : NSObject
302 -(NSArray *)subviews;
303 @end
305 void testNoReportWhenReceiverNil(NSMutableArray *array, int b) {
306   // Don't warn about adding nil to a container when the receiver is also
307   // definitely nil.
308   if (array == 0) {
309     [array addObject:0]; // no-warning
310   }
312   MyView *view = b ? [[MyView alloc] init] : 0;
313   NSMutableArray *subviews = [[view subviews] mutableCopy];
314   // When view is nil, subviews is also nil so there should be no warning
315   // here either.
316   [subviews addObject:view]; // no-warning
319 NSString *getStringFromString(NSString *string) {
320   if (!string)
321     return nil;
322   return @"New String";
324 void testInlinedDefensiveCheck(NSMutableDictionary *dict, id obj) {
325   // The check in getStringFromString() is not a good indication
326   // that 'obj' can be nil in this context.
327   dict[obj] = getStringFromString(obj); // no-warning
330 Foo * getMightBeNullFoo();
331 Foo * _Nonnull getNonnullFoo();
332 Foo * _Nullable getNullableFoo();
334 void testCreateDictionaryLiteralWithNullableArg() {
335   Foo *p1 = getMightBeNullFoo();
336   Foo *p2 = getNonnullFoo();
337   Foo *p3 = getNullableFoo();
339   clang_analyzer_eval(p1 == nil); // expected-warning {{UNKNOWN}}
340   clang_analyzer_eval(p2 == nil); // expected-warning {{UNKNOWN}}
341   clang_analyzer_eval(p3 == nil); // expected-warning {{UNKNOWN}}
343   (void)@{@"abc" : p1}; // no-warning
344   (void)@{@"abc" : p2}; // no-warning
345   (void)@{@"abc" : p3}; // expected-warning {{Nullable pointer is passed to a callee that requires a non-null}}
347   clang_analyzer_eval(p1 == nil); // expected-warning {{FALSE}}
348   clang_analyzer_eval(p2 == nil); // expected-warning {{FALSE}}
349   clang_analyzer_eval(p3 == nil); // expected-warning {{FALSE}}
352 void testCreateArrayLiteralWithNullableArg() {
353   Foo *p1 = getMightBeNullFoo();
354   Foo *p2 = getNonnullFoo();
355   Foo *p3 = getNullableFoo();
357   clang_analyzer_eval(p1 == nil); // expected-warning {{UNKNOWN}}
358   clang_analyzer_eval(p2 == nil); // expected-warning {{UNKNOWN}}
359   clang_analyzer_eval(p3 == nil); // expected-warning {{UNKNOWN}}
361   (void)@[p1]; // no-warning
362   (void)@[p2]; // no-warning
363   (void)@[p3]; // expected-warning {{Nullable pointer is passed to a callee that requires a non-null}}
365   clang_analyzer_eval(p1 == nil); // expected-warning {{FALSE}}
366   clang_analyzer_eval(p2 == nil); // expected-warning {{FALSE}}
367   clang_analyzer_eval(p3 == nil); // expected-warning {{FALSE}}