NSString.m revision 784606f796fa00427aab2f55c8e1025376450a17
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// Test case for passing a tracked object by-reference to a function we 154// don't undersand. 155void unknown_function_f12(NSString** s); 156void f12() { 157 NSString *string = [[NSString alloc] init]; 158 unknown_function_f12(&string); // no-warning 159} 160 161 162@interface C1 : NSObject {} 163- (NSString*) getShared; 164+ (C1*) sharedInstance; 165@end 166@implementation C1 : NSObject {} 167- (NSString*) getShared { 168 static NSString* s = 0; 169 if (!s) s = [[NSString alloc] init]; 170 return s; // no-warning 171} 172+ (C1 *)sharedInstance { 173 static C1 *sharedInstance = 0; 174 if (!sharedInstance) { 175 sharedInstance = [[C1 alloc] init]; 176 } 177 return sharedInstance; // no-warning 178} 179@end 180 181@interface SharedClass : NSObject 182+ (id)sharedInstance; 183@end 184@implementation SharedClass 185 186- (id)_init { 187 if ((self = [super init])) { 188 NSLog(@"Bar"); 189 } 190 return self; 191} 192 193+ (id)sharedInstance { 194 static SharedClass *_sharedInstance = 0; 195 if (!_sharedInstance) { 196 _sharedInstance = [[SharedClass alloc] _init]; 197 } 198 return _sharedInstance; // no-warning 199} 200@end 201