[clang] Handle __declspec() attributes in using
[llvm-project.git] / clang / test / Analysis / NSContainers.m
blobf41189a5e1dcf6294882f6f74f8d1ae302fe9460
1 // RUN: %clang_analyze_cc1  -Wno-objc-literal-conversion -analyzer-checker=core,osx.cocoa.NonNilReturnValue,osx.cocoa.NilArg,osx.cocoa.Loops,debug.ExprInspection -verify -Wno-objc-root-class %s
3 void clang_analyzer_eval(int);
5 #define nil ((id)0)
7 typedef unsigned long NSUInteger;
8 typedef signed char BOOL;
9 typedef struct _NSZone NSZone;
10 @class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
11 @protocol NSObject
12 @end
13 @protocol NSCopying
14 - (id)copyWithZone:(NSZone *)zone;
15 @end
16 @protocol NSMutableCopying
17 - (id)mutableCopyWithZone:(NSZone *)zone;
18 @end
19 @protocol NSCoding
20 - (void)encodeWithCoder:(NSCoder *)aCoder;
21 @end
22 @protocol NSSecureCoding <NSCoding>
23 @required
24 + (BOOL)supportsSecureCoding;
25 @end
26 @interface NSObject <NSObject> {}
27 - (id)init;
28 + (id)alloc;
30 - (id)mutableCopy;
31 @end
33 typedef struct {
34   unsigned long state;
35   id *itemsPtr;
36   unsigned long *mutationsPtr;
37   unsigned long extra[5];
38 } NSFastEnumerationState;
39 @protocol NSFastEnumeration
40 - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id [])buffer count:(NSUInteger)len;
41 @end
43 @interface NSArray : NSObject <NSCopying, NSMutableCopying, NSSecureCoding, NSFastEnumeration>
44 - (NSUInteger)count;
45 - (id)objectAtIndex:(NSUInteger)index;
46 @end
48 @interface NSArray (NSExtendedArray)
49 - (NSArray *)arrayByAddingObject:(id)anObject;
50 - (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)idx __attribute__((availability(macosx,introduced=10.8)));
51 @end
53 @interface NSArray (NSArrayCreation)
54 + (instancetype)arrayWithObjects:(const id [])objects count:(NSUInteger)cnt;
55 @end
57 @interface NSMutableArray : NSArray
59 - (void)addObject:(id)anObject;
60 - (void)insertObject:(id)anObject atIndex:(NSUInteger)index;
61 - (void)removeLastObject;
62 - (void)removeObjectAtIndex:(NSUInteger)index;
63 - (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject;
65 @end
67 @interface NSDictionary : NSObject <NSCopying, NSMutableCopying, NSSecureCoding, NSFastEnumeration>
69 - (NSUInteger)count;
70 - (id)objectForKey:(id)aKey;
71 - (NSEnumerator *)keyEnumerator;
73 @end
75 @interface NSDictionary (NSDictionaryCreation)
77 + (id)dictionary;
78 + (id)dictionaryWithObject:(id)object forKey:(id <NSCopying>)key;
79 + (instancetype)dictionaryWithObjects:(const id [])objects forKeys:(const id <NSCopying> [])keys count:(NSUInteger)cnt;
81 @end
83 @interface NSMutableDictionary : NSDictionary
85 - (void)removeObjectForKey:(id)aKey;
86 - (void)setObject:(id)anObject forKey:(id <NSCopying>)aKey;
88 @end
90 @interface NSMutableDictionary (NSExtendedMutableDictionary)
92 - (void)addEntriesFromDictionary:(NSDictionary *)otherDictionary;
93 - (void)removeAllObjects;
94 - (void)removeObjectsForKeys:(NSArray *)keyArray;
95 - (void)setDictionary:(NSDictionary *)otherDictionary;
96 - (void)setObject:(id)obj forKeyedSubscript:(id <NSCopying>)key __attribute__((availability(macosx,introduced=10.8)));
98 @end
100 @interface NSOrderedSet : NSObject <NSFastEnumeration>
101 @end
102 @interface NSOrderedSet (NSOrderedSetCreation)
103 - (NSUInteger)count;
104 @end
106 @interface NSString : NSObject <NSCopying, NSMutableCopying, NSSecureCoding>
108 @end
110 @interface NSNull : NSObject <NSCopying, NSSecureCoding>
111 + (NSNull *)null;
112 @end
114 // NSMutableArray API
115 void testNilArgNSMutableArray1(void) {
116   NSMutableArray *marray = [[NSMutableArray alloc] init];
117   [marray addObject:0]; // expected-warning {{Argument to 'NSMutableArray' method 'addObject:' cannot be nil}}
120 void testNilArgNSMutableArray2(void) {
121   NSMutableArray *marray = [[NSMutableArray alloc] init];
122   [marray insertObject:0 atIndex:1]; // expected-warning {{Argument to 'NSMutableArray' method 'insertObject:atIndex:' cannot be nil}}
125 void testNilArgNSMutableArray3(void) {
126   NSMutableArray *marray = [[NSMutableArray alloc] init];
127   [marray replaceObjectAtIndex:1 withObject:0]; // expected-warning {{Argument to 'NSMutableArray' method 'replaceObjectAtIndex:withObject:' cannot be nil}}
130 void testNilArgNSMutableArray4(void) {
131   NSMutableArray *marray = [[NSMutableArray alloc] init];
132   [marray setObject:0 atIndexedSubscript:1]; // expected-warning {{Argument to 'NSMutableArray' method 'setObject:atIndexedSubscript:' cannot be nil}}
135 void testNilArgNSMutableArray5(void) {
136   NSMutableArray *marray = [[NSMutableArray alloc] init];
137   marray[1] = 0; // expected-warning {{Array element cannot be nil}}
140 // NSArray API
141 void testNilArgNSArray1(void) {
142   NSArray *array = [[NSArray alloc] init];
143   NSArray *copyArray = [array arrayByAddingObject:0]; // expected-warning {{Argument to 'NSArray' method 'arrayByAddingObject:' cannot be nil}}
146 // NSMutableDictionary and NSDictionary APIs.
147 void testNilArgNSMutableDictionary1(NSMutableDictionary *d, NSString* key) {
148   [d setObject:0 forKey:key]; // expected-warning {{Value argument to 'setObject:forKey:' cannot be nil}}
151 void testNilArgNSMutableDictionary2(NSMutableDictionary *d, NSObject *obj) {
152   [d setObject:obj forKey:0]; // expected-warning {{Key argument to 'setObject:forKey:' cannot be nil}}
155 void testNilArgNSMutableDictionary3(NSMutableDictionary *d) {
156   [d removeObjectForKey:0]; // expected-warning {{Value argument to 'removeObjectForKey:' cannot be nil}}
159 void testNilArgNSMutableDictionary5(NSMutableDictionary *d, NSString* key) {
160   d[key] = 0; // no-warning - removing the mapping for the given key
162 void testNilArgNSMutableDictionary6(NSMutableDictionary *d, NSString *key) {
163   if (key)
164     ;
165   d[key] = 0; // expected-warning {{'NSMutableDictionary' key cannot be nil}}
168 NSDictionary *testNilArgNSDictionary1(NSString* key) {
169   return [NSDictionary dictionaryWithObject:0 forKey:key]; // expected-warning {{Value argument to 'dictionaryWithObject:forKey:' cannot be nil}}
171 NSDictionary *testNilArgNSDictionary2(NSObject *obj) {
172   return [NSDictionary dictionaryWithObject:obj forKey:0]; // expected-warning {{Key argument to 'dictionaryWithObject:forKey:' cannot be nil}}
175 id testCreateDictionaryLiteralKey(id value, id nilKey) {
176   if (nilKey)
177     ;
178   return @{@"abc":value, nilKey:@"abc"}; // expected-warning {{Dictionary key cannot be nil}}
181 id testCreateDictionaryLiteralValue(id nilValue) {
182   if (nilValue)
183     ;
184   return @{@"abc":nilValue}; // expected-warning {{Dictionary value cannot be nil}}
187 id testCreateDictionaryLiteral(id nilValue, id nilKey) {
188   if (nilValue)
189     ;
190   if (nilKey)
191     ;
192   return @{@"abc":nilValue, nilKey:@"abc"}; // expected-warning {{Dictionary key cannot be nil}}
193                                             // expected-warning@-1 {{Dictionary value cannot be nil}}
196 id testCreateArrayLiteral(id myNil) {
197   if (myNil)
198     ;
199   return @[ @"a", myNil, @"c" ]; // expected-warning {{Array element cannot be nil}}
202 // Test inline defensive checks suppression.
203 void idc(id x) {
204   if (x)
205     ;
207 void testIDC(NSMutableDictionary *d, NSString *key) {
208   idc(key);
209   d[key] = @"abc"; // no-warning
212 @interface Foo {
213 @public
214   int x;
216 - (int *)getPtr;
217 - (int)getInt;
218 - (NSMutableDictionary *)getDictPtr;
219 @property (retain, readonly, nonatomic) Foo* data;
220 - (NSString*) stringForKeyFE: (id<NSCopying>)key;
221 @end
223 void idc2(id x) {
224         if (!x)
225                 return;
227 Foo *retNil(void) {
228   return 0;
231 void testIDC2(Foo *obj) {
232         idc2(obj);
233         *[obj getPtr] = 1; // no-warning
236 int testIDC3(Foo *obj) {
237         idc2(obj);
238   return 1/[obj getInt];
241 void testNilReceiverIDC(Foo *obj, NSString *key) {
242         NSMutableDictionary *D = [obj getDictPtr];
243   idc(D);
244   D[key] = @"abc"; // no-warning
247 void testNilReceiverRetNil2(NSMutableDictionary *D, Foo *FooPtrIn, id value) {
248   NSString* const kKeyIdentifier = @"key";
249         Foo *FooPtr = retNil();
250   NSString *key = [[FooPtr data] stringForKeyFE: kKeyIdentifier];
251   // key is nil because FooPtr is nil. However, FooPtr is set to nil inside an
252   // inlined function, so this error report should be suppressed.
253   [D setObject: value forKey: key]; // no-warning
256 void testAssumeNSNullNullReturnsNonNil(NSMutableDictionary *Table, id Object,
257                                       id InValue) {
258   id Value = Object ? [Table objectForKey:Object] : [NSNull null];
259   if (!Value) {
260     Value = InValue;
261     [Table setObject:Value forKey:Object]; // no warning
262   }
265 void testCollectionIsNotEmptyWhenCountIsGreaterThanZero(NSMutableDictionary *D){
266   if ([D count] > 0) { // Count is greater than zero.
267     NSString *s = 0;
268     for (NSString *key in D) {
269       s = key;       // Loop is always entered.
270     }
271     [D removeObjectForKey:s]; // no warning
272   }
275 void testCountAwareNSOrderedSet(NSOrderedSet *containers, int *validptr) {
276         int *x = 0;
277   NSUInteger containerCount = [containers count];
278   if (containerCount > 0)    
279                 x = validptr;
280         for (id c in containers) {
281                 *x = 1; // no warning
282         }
285 void testLiteralsNonNil(void) {
286   clang_analyzer_eval(!!@[]); // expected-warning{{TRUE}}
287   clang_analyzer_eval(!!@{}); // expected-warning{{TRUE}}
290 @interface NSMutableArray (MySafeAdd)
291 - (void)addObject:(id)obj safe:(BOOL)safe;
292 @end
294 void testArrayCategory(NSMutableArray *arr) {
295   [arr addObject:0 safe:1]; // no-warning
298 @interface MyView : NSObject
299 -(NSArray *)subviews;
300 @end
302 void testNoReportWhenReceiverNil(NSMutableArray *array, int b) {
303   // Don't warn about adding nil to a container when the receiver is also
304   // definitely nil.
305   if (array == 0) {
306     [array addObject:0]; // no-warning
307   }
309   MyView *view = b ? [[MyView alloc] init] : 0;
310   NSMutableArray *subviews = [[view subviews] mutableCopy];
311   // When view is nil, subviews is also nil so there should be no warning
312   // here either.
313   [subviews addObject:view]; // no-warning
316 NSString *getStringFromString(NSString *string) {
317   if (!string)
318     return nil;
319   return @"New String";
321 void testInlinedDefensiveCheck(NSMutableDictionary *dict, id obj) {
322   // The check in getStringFromString() is not a good indication
323   // that 'obj' can be nil in this context.
324   dict[obj] = getStringFromString(obj); // no-warning