diff options
Diffstat (limited to 'test/Analysis/NSContainers.m')
-rw-r--r-- | test/Analysis/NSContainers.m | 88 |
1 files changed, 83 insertions, 5 deletions
diff --git a/test/Analysis/NSContainers.m b/test/Analysis/NSContainers.m index 540c7a4..a9e76fb 100644 --- a/test/Analysis/NSContainers.m +++ b/test/Analysis/NSContainers.m @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.NilArg -verify -Wno-objc-root-class %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.NonNilReturnValue,osx.cocoa.NilArg,osx.cocoa.Loops -verify -Wno-objc-root-class %s typedef unsigned long NSUInteger; typedef signed char BOOL; typedef struct _NSZone NSZone; @@ -14,8 +14,6 @@ typedef struct _NSZone NSZone; @protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @end -@protocol NSFastEnumeration -@end @protocol NSSecureCoding <NSCoding> @required + (BOOL)supportsSecureCoding; @@ -24,11 +22,20 @@ typedef struct _NSZone NSZone; - (id)init; + (id)alloc; @end -@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSSecureCoding, NSFastEnumeration> +typedef struct { + unsigned long state; + id *itemsPtr; + unsigned long *mutationsPtr; + unsigned long extra[5]; +} NSFastEnumerationState; +@protocol NSFastEnumeration +- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id [])buffer count:(NSUInteger)len; +@end + +@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSSecureCoding, NSFastEnumeration> - (NSUInteger)count; - (id)objectAtIndex:(NSUInteger)index; - @end @interface NSArray (NSExtendedArray) @@ -36,6 +43,10 @@ typedef struct _NSZone NSZone; - (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)idx __attribute__((availability(macosx,introduced=10.8))); @end +@interface NSArray (NSArrayCreation) ++ (instancetype)arrayWithObjects:(const id [])objects count:(NSUInteger)cnt; +@end + @interface NSMutableArray : NSArray - (void)addObject:(id)anObject; @@ -58,6 +69,8 @@ typedef struct _NSZone NSZone; + (id)dictionary; + (id)dictionaryWithObject:(id)object forKey:(id <NSCopying>)key; ++ (instancetype)dictionaryWithObjects:(const id [])objects forKeys:(const id <NSCopying> [])keys count:(NSUInteger)cnt; + @end @interface NSMutableDictionary : NSDictionary @@ -77,10 +90,20 @@ typedef struct _NSZone NSZone; @end +@interface NSOrderedSet : NSObject <NSFastEnumeration> +@end +@interface NSOrderedSet (NSOrderedSetCreation) +- (NSUInteger)count; +@end + @interface NSString : NSObject <NSCopying, NSMutableCopying, NSSecureCoding> @end +@interface NSNull : NSObject <NSCopying, NSSecureCoding> ++ (NSNull *)null; +@end + // NSMutableArray API void testNilArgNSMutableArray1() { NSMutableArray *marray = [[NSMutableArray alloc] init]; @@ -143,6 +166,33 @@ NSDictionary *testNilArgNSDictionary2(NSObject *obj) { return [NSDictionary dictionaryWithObject:obj forKey:0]; // expected-warning {{Key argument to 'dictionaryWithObject:forKey:' cannot be nil}} } +id testCreateDictionaryLiteralKey(id value, id nilKey) { + if (nilKey) + ; + return @{@"abc":value, nilKey:@"abc"}; // expected-warning {{Dictionary key cannot be nil}} +} + +id testCreateDictionaryLiteralValue(id nilValue) { + if (nilValue) + ; + return @{@"abc":nilValue}; // expected-warning {{Dictionary value cannot be nil}} +} + +id testCreateDictionaryLiteral(id nilValue, id nilKey) { + if (nilValue) + ; + if (nilKey) + ; + return @{@"abc":nilValue, nilKey:@"abc"}; // expected-warning {{Dictionary key cannot be nil}} + // expected-warning@-1 {{Dictionary value cannot be nil}} +} + +id testCreateArrayLiteral(id myNil) { + if (myNil) + ; + return @[ @"a", myNil, @"c" ]; // expected-warning {{Array element cannot be nil}} +} + // Test inline defensive checks suppression. void idc(id x) { if (x) @@ -197,4 +247,32 @@ void testNilReceiverRetNil2(NSMutableDictionary *D, Foo *FooPtrIn, id value) { [D setObject: value forKey: key]; // no-warning } +void testAssumeNSNullNullReturnsNonNil(NSMutableDictionary *Table, id Object, + id InValue) { + id Value = Object ? [Table objectForKey:Object] : [NSNull null]; + if (!Value) { + Value = InValue; + [Table setObject:Value forKey:Object]; // no warning + } +} + +void testCollectionIsNotEmptyWhenCountIsGreaterThanZero(NSMutableDictionary *D){ + if ([D count] > 0) { // Count is greater than zero. + NSString *s = 0; + for (NSString *key in D) { + s = key; // Loop is always entered. + } + [D removeObjectForKey:s]; // no warning + } +} + +void testCountAwareNSOrderedSet(NSOrderedSet *containers, int *validptr) { + int *x = 0; + NSUInteger containerCount = [containers count]; + if (containerCount > 0) + x = validptr; + for (id c in containers) { + *x = 1; // no warning + } +} |