NSString.m revision 2fb78a70536274426302415b6fc54a1074788e91
1// RUN: clang -checker-cfref -verify %s 2 3//===----------------------------------------------------------------------===// 4// The following code is reduced using delta-debugging from 5// Foundation.h (Mac OS X). 6// 7// It includes the basic definitions for the test cases below. 8// Not directly including Foundation.h directly makes this test case 9// both svelte and portable to non-Mac platforms. 10//===----------------------------------------------------------------------===// 11 12typedef const void * CFTypeRef; 13typedef const struct __CFString * CFStringRef; 14typedef const struct __CFAllocator * CFAllocatorRef; 15extern const CFAllocatorRef kCFAllocatorDefault; 16extern CFTypeRef CFRetain(CFTypeRef cf); 17typedef const struct __CFDictionary * CFDictionaryRef; 18const void *CFDictionaryGetValue(CFDictionaryRef theDict, const void *key); 19extern CFStringRef CFStringCreateWithFormat(CFAllocatorRef alloc, CFDictionaryRef formatOptions, CFStringRef format, ...); 20typedef signed char BOOL; 21typedef int NSInteger; 22typedef unsigned int NSUInteger; 23@class NSString, Protocol; 24extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2))); 25typedef NSInteger NSComparisonResult; 26typedef struct _NSZone NSZone; 27@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; 28@protocol NSObject 29- (BOOL)isEqual:(id)object; 30- (oneway void)release; 31- (id)retain; 32@end 33@protocol NSCopying 34- (id)copyWithZone:(NSZone *)zone; 35@end 36@protocol NSMutableCopying 37- (id)mutableCopyWithZone:(NSZone *)zone; 38@end 39@protocol NSCoding 40- (void)encodeWithCoder:(NSCoder *)aCoder; 41@end 42@interface NSObject <NSObject> {} 43- (id)init; 44+ (id)alloc; 45@end 46extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone); 47typedef struct {} NSFastEnumerationState; 48@protocol NSFastEnumeration 49- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len; 50@end 51@class NSString; 52typedef struct _NSRange {} NSRange; 53@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration> 54- (NSUInteger)count; 55@end 56@interface NSMutableArray : NSArray 57- (void)addObject:(id)anObject; 58- (id)initWithCapacity:(NSUInteger)numItems; 59@end 60typedef unsigned short unichar; 61@class NSData, NSArray, NSDictionary, NSCharacterSet, NSData, NSURL, NSError, NSLocale; 62typedef NSUInteger NSStringCompareOptions; 63@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding> - (NSUInteger)length; 64- (NSComparisonResult)compare:(NSString *)string; 65- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask; 66- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask range:(NSRange)compareRange; 67- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask range:(NSRange)compareRange locale:(id)locale; 68- (NSComparisonResult)caseInsensitiveCompare:(NSString *)string; 69- (NSArray *)componentsSeparatedByCharactersInSet:(NSCharacterSet *)separator; 70@end 71@interface NSSimpleCString : NSString {} @end 72@interface NSConstantString : NSSimpleCString @end 73extern void *_NSConstantStringClassReference; 74 75//===----------------------------------------------------------------------===// 76// Test cases. 77//===----------------------------------------------------------------------===// 78 79NSComparisonResult f1(NSString* s) { 80 NSString *aString = 0; 81 return [s compare:aString]; // expected-warning {{Argument to 'NSString' method 'compare:' cannot be nil.}} 82} 83 84NSComparisonResult f2(NSString* s) { 85 NSString *aString = 0; 86 return [s caseInsensitiveCompare:aString]; // expected-warning {{Argument to 'NSString' method 'caseInsensitiveCompare:' cannot be nil.}} 87} 88 89NSComparisonResult f3(NSString* s, NSStringCompareOptions op) { 90 NSString *aString = 0; 91 return [s compare:aString options:op]; // expected-warning {{Argument to 'NSString' method 'compare:options:' cannot be nil.}} 92} 93 94NSComparisonResult f4(NSString* s, NSStringCompareOptions op, NSRange R) { 95 NSString *aString = 0; 96 return [s compare:aString options:op range:R]; // expected-warning {{Argument to 'NSString' method 'compare:options:range:' cannot be nil.}} 97} 98 99NSComparisonResult f5(NSString* s, NSStringCompareOptions op, NSRange R) { 100 NSString *aString = 0; 101 return [s compare:aString options:op range:R locale:0]; // expected-warning {{Argument to 'NSString' method 'compare:options:range:locale:' cannot be nil.}} 102} 103 104NSArray *f6(NSString* s) { 105 return [s componentsSeparatedByCharactersInSet:0]; // expected-warning {{Argument to 'NSString' method 'componentsSeparatedByCharactersInSet:' cannot be nil.}} 106} 107 108NSString* f7(NSString* s1, NSString* s2, NSString* s3) { 109 110 NSString* s4 = (NSString*) 111 CFStringCreateWithFormat(kCFAllocatorDefault, 0, 112 (CFStringRef) __builtin___CFStringMakeConstantString("%@ %@ (%@)"), 113 s1, s2, s3); 114 115 CFRetain(s4); 116 return s4; // expected-warning{{leak}} 117} 118 119NSMutableArray* f8() { 120 121 NSString* s = [[NSString alloc] init]; 122 NSMutableArray* a = [[NSMutableArray alloc] initWithCapacity:2]; 123 [a addObject:s]; 124 [s release]; // no-warning 125 return a; 126} 127 128void f9() { 129 130 NSString* s = [[NSString alloc] init]; 131 NSString* q = s; 132 [s release]; 133 [q release]; // expected-warning {{used after it is released}} 134} 135 136NSString* f10() { 137 static NSString* s = 0; 138 if (!s) s = [[NSString alloc] init]; 139 return s; // no-warning 140} 141 142// Test case for regression reported in <rdar://problem/6452745>. 143// Essentially 's' should not be considered allocated on the false branch. 144// This exercises the 'EvalAssume' logic in GRTransferFuncs (CFRefCount.cpp). 145NSString* f11(CFDictionaryRef dict, const char* key) { 146 NSString* s = (NSString*) CFDictionaryGetValue(dict, key); 147 [s retain]; 148 if (s) { 149 [s release]; 150 } 151} 152 153@interface C1 : NSObject {} 154- (NSString*) getShared; 155+ (C1*) sharedInstance; 156@end 157@implementation C1 : NSObject {} 158- (NSString*) getShared { 159 static NSString* s = 0; 160 if (!s) s = [[NSString alloc] init]; 161 return s; // no-warning 162} 163+ (C1 *)sharedInstance { 164 static C1 *sharedInstance = 0; 165 if (!sharedInstance) { 166 sharedInstance = [[C1 alloc] init]; 167 } 168 return sharedInstance; // no-warning 169} 170@end 171 172@interface SharedClass : NSObject 173+ (id)sharedInstance; 174@end 175@implementation SharedClass 176 177- (id)_init { 178 if ((self = [super init])) { 179 NSLog(@"Bar"); 180 } 181 return self; 182} 183 184+ (id)sharedInstance { 185 static SharedClass *_sharedInstance = 0; 186 if (!_sharedInstance) { 187 _sharedInstance = [[SharedClass alloc] _init]; 188 } 189 return _sharedInstance; // no-warning 190} 191@end 192