blob: 402ce2c90a1795aa155817363fd3e9d179b4b2f6 [file] [log] [blame]
Stephen Hines176edba2014-12-01 14:53:08 -08001// RUN: %clang_cc1 -Wno-objc-literal-conversion -analyze -analyzer-checker=core,osx.cocoa.NonNilReturnValue,osx.cocoa.NilArg,osx.cocoa.Loops,debug.ExprInspection -verify -Wno-objc-root-class %s
Stephen Hines651f13c2014-04-23 16:59:28 -07002
3void clang_analyzer_eval(int);
4
Anna Zaks4b94f4d2013-03-18 20:46:56 +00005typedef unsigned long NSUInteger;
6typedef signed char BOOL;
7typedef struct _NSZone NSZone;
8@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
9@protocol NSObject
10@end
11@protocol NSCopying
12- (id)copyWithZone:(NSZone *)zone;
13@end
14@protocol NSMutableCopying
15- (id)mutableCopyWithZone:(NSZone *)zone;
16@end
17@protocol NSCoding
18- (void)encodeWithCoder:(NSCoder *)aCoder;
19@end
Anna Zaks4b94f4d2013-03-18 20:46:56 +000020@protocol NSSecureCoding <NSCoding>
21@required
22+ (BOOL)supportsSecureCoding;
23@end
24@interface NSObject <NSObject> {}
25- (id)init;
26+ (id)alloc;
27@end
Anna Zaks4b94f4d2013-03-18 20:46:56 +000028
Anna Zaks2ffcd182013-06-22 00:23:26 +000029typedef struct {
30 unsigned long state;
31 id *itemsPtr;
32 unsigned long *mutationsPtr;
33 unsigned long extra[5];
34} NSFastEnumerationState;
35@protocol NSFastEnumeration
36- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id [])buffer count:(NSUInteger)len;
37@end
38
39@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSSecureCoding, NSFastEnumeration>
Anna Zaks4b94f4d2013-03-18 20:46:56 +000040- (NSUInteger)count;
41- (id)objectAtIndex:(NSUInteger)index;
Anna Zaks4b94f4d2013-03-18 20:46:56 +000042@end
43
44@interface NSArray (NSExtendedArray)
45- (NSArray *)arrayByAddingObject:(id)anObject;
46- (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)idx __attribute__((availability(macosx,introduced=10.8)));
47@end
48
Anna Zaksb834a782013-05-13 21:48:20 +000049@interface NSArray (NSArrayCreation)
50+ (instancetype)arrayWithObjects:(const id [])objects count:(NSUInteger)cnt;
51@end
52
Anna Zaks4b94f4d2013-03-18 20:46:56 +000053@interface NSMutableArray : NSArray
54
55- (void)addObject:(id)anObject;
56- (void)insertObject:(id)anObject atIndex:(NSUInteger)index;
57- (void)removeLastObject;
58- (void)removeObjectAtIndex:(NSUInteger)index;
59- (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject;
60
61@end
62
Anna Zaksb0957822013-03-23 00:39:21 +000063@interface NSDictionary : NSObject <NSCopying, NSMutableCopying, NSSecureCoding, NSFastEnumeration>
64
65- (NSUInteger)count;
66- (id)objectForKey:(id)aKey;
67- (NSEnumerator *)keyEnumerator;
68
69@end
70
71@interface NSDictionary (NSDictionaryCreation)
72
73+ (id)dictionary;
74+ (id)dictionaryWithObject:(id)object forKey:(id <NSCopying>)key;
Anna Zaksb834a782013-05-13 21:48:20 +000075+ (instancetype)dictionaryWithObjects:(const id [])objects forKeys:(const id <NSCopying> [])keys count:(NSUInteger)cnt;
76
Anna Zaksb0957822013-03-23 00:39:21 +000077@end
78
79@interface NSMutableDictionary : NSDictionary
80
81- (void)removeObjectForKey:(id)aKey;
82- (void)setObject:(id)anObject forKey:(id <NSCopying>)aKey;
83
84@end
85
86@interface NSMutableDictionary (NSExtendedMutableDictionary)
87
88- (void)addEntriesFromDictionary:(NSDictionary *)otherDictionary;
89- (void)removeAllObjects;
90- (void)removeObjectsForKeys:(NSArray *)keyArray;
91- (void)setDictionary:(NSDictionary *)otherDictionary;
92- (void)setObject:(id)obj forKeyedSubscript:(id <NSCopying>)key __attribute__((availability(macosx,introduced=10.8)));
93
94@end
95
Anna Zaks741c5412013-11-04 19:13:08 +000096@interface NSOrderedSet : NSObject <NSFastEnumeration>
97@end
98@interface NSOrderedSet (NSOrderedSetCreation)
99- (NSUInteger)count;
100@end
101
Anna Zaksb0957822013-03-23 00:39:21 +0000102@interface NSString : NSObject <NSCopying, NSMutableCopying, NSSecureCoding>
103
104@end
105
Anna Zaksf2d8fbe2013-05-10 18:04:46 +0000106@interface NSNull : NSObject <NSCopying, NSSecureCoding>
107+ (NSNull *)null;
108@end
109
Anna Zaks4b94f4d2013-03-18 20:46:56 +0000110// NSMutableArray API
Anna Zaksb0957822013-03-23 00:39:21 +0000111void testNilArgNSMutableArray1() {
Anna Zaks4b94f4d2013-03-18 20:46:56 +0000112 NSMutableArray *marray = [[NSMutableArray alloc] init];
113 [marray addObject:0]; // expected-warning {{Argument to 'NSMutableArray' method 'addObject:' cannot be nil}}
114}
115
Anna Zaksb0957822013-03-23 00:39:21 +0000116void testNilArgNSMutableArray2() {
Anna Zaks4b94f4d2013-03-18 20:46:56 +0000117 NSMutableArray *marray = [[NSMutableArray alloc] init];
118 [marray insertObject:0 atIndex:1]; // expected-warning {{Argument to 'NSMutableArray' method 'insertObject:atIndex:' cannot be nil}}
119}
120
Anna Zaksb0957822013-03-23 00:39:21 +0000121void testNilArgNSMutableArray3() {
Anna Zaks4b94f4d2013-03-18 20:46:56 +0000122 NSMutableArray *marray = [[NSMutableArray alloc] init];
123 [marray replaceObjectAtIndex:1 withObject:0]; // expected-warning {{Argument to 'NSMutableArray' method 'replaceObjectAtIndex:withObject:' cannot be nil}}
124}
125
Anna Zaksb0957822013-03-23 00:39:21 +0000126void testNilArgNSMutableArray4() {
Anna Zaks4b94f4d2013-03-18 20:46:56 +0000127 NSMutableArray *marray = [[NSMutableArray alloc] init];
128 [marray setObject:0 atIndexedSubscript:1]; // expected-warning {{Argument to 'NSMutableArray' method 'setObject:atIndexedSubscript:' cannot be nil}}
129}
130
Anna Zaksb0957822013-03-23 00:39:21 +0000131void testNilArgNSMutableArray5() {
132 NSMutableArray *marray = [[NSMutableArray alloc] init];
133 marray[1] = 0; // expected-warning {{Array element cannot be nil}}
134}
135
Anna Zaks4b94f4d2013-03-18 20:46:56 +0000136// NSArray API
Anna Zaksb0957822013-03-23 00:39:21 +0000137void testNilArgNSArray1() {
Anna Zaks4b94f4d2013-03-18 20:46:56 +0000138 NSArray *array = [[NSArray alloc] init];
139 NSArray *copyArray = [array arrayByAddingObject:0]; // expected-warning {{Argument to 'NSArray' method 'arrayByAddingObject:' cannot be nil}}
140}
141
Anna Zaksb0957822013-03-23 00:39:21 +0000142// NSMutableDictionary and NSDictionary APIs.
143void testNilArgNSMutableDictionary1(NSMutableDictionary *d, NSString* key) {
Anna Zaks24cac5a2013-04-05 23:50:18 +0000144 [d setObject:0 forKey:key]; // expected-warning {{Value argument to 'setObject:forKey:' cannot be nil}}
Anna Zaksb0957822013-03-23 00:39:21 +0000145}
146
147void testNilArgNSMutableDictionary2(NSMutableDictionary *d, NSObject *obj) {
Anna Zaks24cac5a2013-04-05 23:50:18 +0000148 [d setObject:obj forKey:0]; // expected-warning {{Key argument to 'setObject:forKey:' cannot be nil}}
Anna Zaksb0957822013-03-23 00:39:21 +0000149}
150
151void testNilArgNSMutableDictionary3(NSMutableDictionary *d) {
Anna Zaks24cac5a2013-04-05 23:50:18 +0000152 [d removeObjectForKey:0]; // expected-warning {{Value argument to 'removeObjectForKey:' cannot be nil}}
Anna Zaksb0957822013-03-23 00:39:21 +0000153}
154
155void testNilArgNSMutableDictionary5(NSMutableDictionary *d, NSString* key) {
Ted Kremenekf34cb3d2013-04-08 18:09:16 +0000156 d[key] = 0; // expected-warning {{Value stored into 'NSMutableDictionary' cannot be nil}}
Anna Zaksb0957822013-03-23 00:39:21 +0000157}
158void testNilArgNSMutableDictionary6(NSMutableDictionary *d, NSString *key) {
159 if (key)
160 ;
Anna Zaks24cac5a2013-04-05 23:50:18 +0000161 d[key] = 0; // expected-warning {{'NSMutableDictionary' key cannot be nil}}
Ted Kremenekf34cb3d2013-04-08 18:09:16 +0000162 // expected-warning@-1 {{Value stored into 'NSMutableDictionary' cannot be nil}}
Anna Zaksb0957822013-03-23 00:39:21 +0000163}
164
165NSDictionary *testNilArgNSDictionary1(NSString* key) {
Anna Zaks24cac5a2013-04-05 23:50:18 +0000166 return [NSDictionary dictionaryWithObject:0 forKey:key]; // expected-warning {{Value argument to 'dictionaryWithObject:forKey:' cannot be nil}}
Anna Zaksb0957822013-03-23 00:39:21 +0000167}
168NSDictionary *testNilArgNSDictionary2(NSObject *obj) {
Anna Zaks24cac5a2013-04-05 23:50:18 +0000169 return [NSDictionary dictionaryWithObject:obj forKey:0]; // expected-warning {{Key argument to 'dictionaryWithObject:forKey:' cannot be nil}}
Anna Zaksb0957822013-03-23 00:39:21 +0000170}
Anna Zaks15338332013-03-26 23:58:49 +0000171
Anna Zaksb834a782013-05-13 21:48:20 +0000172id testCreateDictionaryLiteralKey(id value, id nilKey) {
173 if (nilKey)
174 ;
175 return @{@"abc":value, nilKey:@"abc"}; // expected-warning {{Dictionary key cannot be nil}}
176}
177
178id testCreateDictionaryLiteralValue(id nilValue) {
179 if (nilValue)
180 ;
181 return @{@"abc":nilValue}; // expected-warning {{Dictionary value cannot be nil}}
182}
183
184id testCreateDictionaryLiteral(id nilValue, id nilKey) {
185 if (nilValue)
186 ;
187 if (nilKey)
188 ;
189 return @{@"abc":nilValue, nilKey:@"abc"}; // expected-warning {{Dictionary key cannot be nil}}
190 // expected-warning@-1 {{Dictionary value cannot be nil}}
191}
192
193id testCreateArrayLiteral(id myNil) {
194 if (myNil)
195 ;
196 return @[ @"a", myNil, @"c" ]; // expected-warning {{Array element cannot be nil}}
197}
198
Anna Zaks15338332013-03-26 23:58:49 +0000199// Test inline defensive checks suppression.
200void idc(id x) {
201 if (x)
202 ;
203}
204void testIDC(NSMutableDictionary *d, NSString *key) {
205 idc(key);
206 d[key] = @"abc"; // no-warning
207}
208
Anna Zaksaabb4c52013-03-28 23:15:22 +0000209@interface Foo {
210@public
211 int x;
212}
Anna Zaks15338332013-03-26 23:58:49 +0000213- (int *)getPtr;
214- (int)getInt;
Anna Zaksaabb4c52013-03-28 23:15:22 +0000215- (NSMutableDictionary *)getDictPtr;
216@property (retain, readonly, nonatomic) Foo* data;
217- (NSString*) stringForKeyFE: (id<NSCopying>)key;
Anna Zaks15338332013-03-26 23:58:49 +0000218@end
219
220void idc2(id x) {
221 if (!x)
222 return;
223}
Anna Zaksaabb4c52013-03-28 23:15:22 +0000224Foo *retNil() {
225 return 0;
226}
Anna Zaks15338332013-03-26 23:58:49 +0000227
228void testIDC2(Foo *obj) {
229 idc2(obj);
230 *[obj getPtr] = 1; // no-warning
231}
232
233int testIDC3(Foo *obj) {
234 idc2(obj);
235 return 1/[obj getInt];
236}
237
Anna Zaksaabb4c52013-03-28 23:15:22 +0000238void testNilReceiverIDC(Foo *obj, NSString *key) {
239 NSMutableDictionary *D = [obj getDictPtr];
240 idc(D);
241 D[key] = @"abc"; // no-warning
242}
243
244void testNilReceiverRetNil2(NSMutableDictionary *D, Foo *FooPtrIn, id value) {
245 NSString* const kKeyIdentifier = @"key";
246 Foo *FooPtr = retNil();
247 NSString *key = [[FooPtr data] stringForKeyFE: kKeyIdentifier];
248 // key is nil because FooPtr is nil. However, FooPtr is set to nil inside an
249 // inlined function, so this error report should be suppressed.
250 [D setObject: value forKey: key]; // no-warning
251}
252
Anna Zaksf2d8fbe2013-05-10 18:04:46 +0000253void testAssumeNSNullNullReturnsNonNil(NSMutableDictionary *Table, id Object,
254 id InValue) {
255 id Value = Object ? [Table objectForKey:Object] : [NSNull null];
256 if (!Value) {
257 Value = InValue;
258 [Table setObject:Value forKey:Object]; // no warning
259 }
260}
261
Anna Zaks2ffcd182013-06-22 00:23:26 +0000262void testCollectionIsNotEmptyWhenCountIsGreaterThanZero(NSMutableDictionary *D){
263 if ([D count] > 0) { // Count is greater than zero.
264 NSString *s = 0;
265 for (NSString *key in D) {
266 s = key; // Loop is always entered.
267 }
268 [D removeObjectForKey:s]; // no warning
269 }
270}
271
Anna Zaks741c5412013-11-04 19:13:08 +0000272void testCountAwareNSOrderedSet(NSOrderedSet *containers, int *validptr) {
273 int *x = 0;
274 NSUInteger containerCount = [containers count];
275 if (containerCount > 0)
276 x = validptr;
277 for (id c in containers) {
278 *x = 1; // no warning
279 }
280}
Anna Zaksaabb4c52013-03-28 23:15:22 +0000281
Stephen Hines651f13c2014-04-23 16:59:28 -0700282void testLiteralsNonNil() {
283 clang_analyzer_eval(!!@[]); // expected-warning{{TRUE}}
284 clang_analyzer_eval(!!@{}); // expected-warning{{TRUE}}
285}
286
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700287@interface NSMutableArray (MySafeAdd)
288- (void)addObject:(id)obj safe:(BOOL)safe;
289@end
290
291void testArrayCategory(NSMutableArray *arr) {
292 [arr addObject:0 safe:1]; // no-warning
293}
294