1*67e74705SXin Li// RUN: %clang_cc1 -triple %itanium_abi_triple -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -analyzer-max-loop 6 -verify %s 2*67e74705SXin Li 3*67e74705SXin Li//===----------------------------------------------------------------------===// 4*67e74705SXin Li// The following code is reduced using delta-debugging from 5*67e74705SXin Li// Foundation.h (Mac OS X). 6*67e74705SXin Li// 7*67e74705SXin Li// It includes the basic definitions for the test cases below. 8*67e74705SXin Li// Not including Foundation.h directly makes this test case both svelte and 9*67e74705SXin Li// portable to non-Mac platforms. 10*67e74705SXin Li//===----------------------------------------------------------------------===// 11*67e74705SXin Li 12*67e74705SXin Litypedef unsigned int __darwin_natural_t; 13*67e74705SXin Litypedef unsigned long UInt32; 14*67e74705SXin Litypedef signed long CFIndex; 15*67e74705SXin Litypedef const void * CFTypeRef; 16*67e74705SXin Litypedef const struct __CFString * CFStringRef; 17*67e74705SXin Litypedef const struct __CFAllocator * CFAllocatorRef; 18*67e74705SXin Liextern const CFAllocatorRef kCFAllocatorDefault; 19*67e74705SXin Liextern CFTypeRef CFRetain(CFTypeRef cf); 20*67e74705SXin Liextern void CFRelease(CFTypeRef cf); 21*67e74705SXin Litypedef struct { 22*67e74705SXin Li} 23*67e74705SXin LiCFArrayCallBacks; 24*67e74705SXin Liextern const CFArrayCallBacks kCFTypeArrayCallBacks; 25*67e74705SXin Litypedef const struct __CFArray * CFArrayRef; 26*67e74705SXin Litypedef struct __CFArray * CFMutableArrayRef; 27*67e74705SXin Liextern CFMutableArrayRef CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFArrayCallBacks *callBacks); 28*67e74705SXin Liextern const void *CFArrayGetValueAtIndex(CFArrayRef theArray, CFIndex idx); 29*67e74705SXin Litypedef const struct __CFDictionary * CFDictionaryRef; 30*67e74705SXin Litypedef UInt32 CFStringEncoding; 31*67e74705SXin Lienum { 32*67e74705SXin LikCFStringEncodingMacRoman = 0, kCFStringEncodingWindowsLatin1 = 0x0500, kCFStringEncodingISOLatin1 = 0x0201, kCFStringEncodingNextStepLatin = 0x0B01, kCFStringEncodingASCII = 0x0600, kCFStringEncodingUnicode = 0x0100, kCFStringEncodingUTF8 = 0x08000100, kCFStringEncodingNonLossyASCII = 0x0BFF , kCFStringEncodingUTF16 = 0x0100, kCFStringEncodingUTF16BE = 0x10000100, kCFStringEncodingUTF16LE = 0x14000100, kCFStringEncodingUTF32 = 0x0c000100, kCFStringEncodingUTF32BE = 0x18000100, kCFStringEncodingUTF32LE = 0x1c000100 }; 33*67e74705SXin Liextern CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding); 34*67e74705SXin Litypedef double CFTimeInterval; 35*67e74705SXin Litypedef CFTimeInterval CFAbsoluteTime; 36*67e74705SXin Litypedef const struct __CFDate * CFDateRef; 37*67e74705SXin Liextern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at); 38*67e74705SXin Liextern CFAbsoluteTime CFDateGetAbsoluteTime(CFDateRef theDate); 39*67e74705SXin Litypedef __darwin_natural_t natural_t; 40*67e74705SXin Litypedef natural_t mach_port_name_t; 41*67e74705SXin Litypedef mach_port_name_t mach_port_t; 42*67e74705SXin Litypedef signed char BOOL; 43*67e74705SXin Litypedef struct _NSZone NSZone; 44*67e74705SXin Li@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; 45*67e74705SXin Li@protocol NSObject 46*67e74705SXin Li- (BOOL)isEqual:(id)object; 47*67e74705SXin Li- (id)retain; 48*67e74705SXin Li- (oneway void)release; 49*67e74705SXin Li@end @protocol NSCopying - (id)copyWithZone:(NSZone *)zone; 50*67e74705SXin Li@end @protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; 51*67e74705SXin Li@end 52*67e74705SXin Li@interface NSObject <NSObject> {} 53*67e74705SXin Li- (id)init; 54*67e74705SXin Li+ (id)allocWithZone:(NSZone *)zone; 55*67e74705SXin Li+ (id)alloc; 56*67e74705SXin Li- (void)dealloc; 57*67e74705SXin Li@end 58*67e74705SXin Litypedef float CGFloat; 59*67e74705SXin Litypedef double NSTimeInterval; 60*67e74705SXin Li@interface NSDate : NSObject <NSCopying, NSCoding> - (NSTimeInterval)timeIntervalSinceReferenceDate; 61*67e74705SXin Li@end enum { 62*67e74705SXin LiNSObjCNoType = 0, NSObjCVoidType = 'v', NSObjCCharType = 'c', NSObjCShortType = 's', NSObjCLongType = 'l', NSObjCLonglongType = 'q', NSObjCFloatType = 'f', NSObjCDoubleType = 'd', NSObjCBoolType = 'B', NSObjCSelectorType = ':', NSObjCObjectType = '@', NSObjCStructType = '{', NSObjCPointerType = '^', NSObjCStringType = '*', NSObjCArrayType = '[', NSObjCUnionType = '(', NSObjCBitfield = 'b' } 63*67e74705SXin Li__attribute__((deprecated)); 64*67e74705SXin Litypedef int kern_return_t; 65*67e74705SXin Litypedef kern_return_t mach_error_t; 66*67e74705SXin Litypedef mach_port_t io_object_t; 67*67e74705SXin Litypedef io_object_t io_service_t; 68*67e74705SXin Litypedef struct __DASession * DASessionRef; 69*67e74705SXin Liextern DASessionRef DASessionCreate( CFAllocatorRef allocator ); 70*67e74705SXin Litypedef struct __DADisk * DADiskRef; 71*67e74705SXin Liextern DADiskRef DADiskCreateFromBSDName( CFAllocatorRef allocator, DASessionRef session, const char * name ); 72*67e74705SXin Liextern DADiskRef DADiskCreateFromIOMedia( CFAllocatorRef allocator, DASessionRef session, io_service_t media ); 73*67e74705SXin Liextern CFDictionaryRef DADiskCopyDescription( DADiskRef disk ); 74*67e74705SXin Liextern DADiskRef DADiskCopyWholeDisk( DADiskRef disk ); 75*67e74705SXin Li@interface NSAppleEventManager : NSObject { 76*67e74705SXin Li} 77*67e74705SXin Li@end enum { 78*67e74705SXin LikDAReturnSuccess = 0, kDAReturnError = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x01, kDAReturnBusy = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x02, kDAReturnBadArgument = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x03, kDAReturnExclusiveAccess = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x04, kDAReturnNoResources = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x05, kDAReturnNotFound = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x06, kDAReturnNotMounted = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x07, kDAReturnNotPermitted = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x08, kDAReturnNotPrivileged = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x09, kDAReturnNotReady = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0A, kDAReturnNotWritable = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0B, kDAReturnUnsupported = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0C }; 79*67e74705SXin Litypedef mach_error_t DAReturn; 80*67e74705SXin Litypedef const struct __DADissenter * DADissenterRef; 81*67e74705SXin Liextern DADissenterRef DADissenterCreate( CFAllocatorRef allocator, DAReturn status, CFStringRef string ); 82*67e74705SXin Li@interface NSNumber : NSObject 83*67e74705SXin Li- (id)initWithInt:(int)value; 84*67e74705SXin Li@end 85*67e74705SXin Litypedef unsigned long NSUInteger; 86*67e74705SXin Li@interface NSArray : NSObject 87*67e74705SXin Li-(id) initWithObjects:(const id *)objects count:(NSUInteger) cnt; 88*67e74705SXin Li@end 89*67e74705SXin Li 90*67e74705SXin Li//===----------------------------------------------------------------------===// 91*67e74705SXin Li// Test cases. 92*67e74705SXin Li//===----------------------------------------------------------------------===// 93*67e74705SXin Li 94*67e74705SXin Li// Test to see if we *issue* an error when we store the pointer 95*67e74705SXin Li// to a struct. This differs from basic store. 96*67e74705SXin Li 97*67e74705SXin LiCFAbsoluteTime CFAbsoluteTimeGetCurrent(void); 98*67e74705SXin Li 99*67e74705SXin Listruct foo { 100*67e74705SXin Li NSDate* f; 101*67e74705SXin Li}; 102*67e74705SXin Li 103*67e74705SXin Li// FIXME: We should be warning about a use-after-free here, but we 104*67e74705SXin Li// temporarily "escape" retain counted objects stored to structs very eagerly 105*67e74705SXin Li// until we can properly tell whether they have escaped via a return value 106*67e74705SXin Li// or not. 107*67e74705SXin LiCFAbsoluteTime f4() { 108*67e74705SXin Li struct foo x; 109*67e74705SXin Li 110*67e74705SXin Li CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); 111*67e74705SXin Li CFDateRef date = CFDateCreate(0, t); 112*67e74705SXin Li [((NSDate*) date) retain]; 113*67e74705SXin Li CFRelease(date); 114*67e74705SXin Li CFDateGetAbsoluteTime(date); // no-warning 115*67e74705SXin Li x.f = (NSDate*) date; 116*67e74705SXin Li [((NSDate*) date) release]; 117*67e74705SXin Li // FIXME: the following line should warn. 118*67e74705SXin Li t = CFDateGetAbsoluteTime(date); // no-warning 119*67e74705SXin Li return t; 120*67e74705SXin Li} 121*67e74705SXin Li 122*67e74705SXin Li// Test that assigning to an self.ivar loses track of an object. 123*67e74705SXin Li// This is a temporary hack to reduce false positives. 124*67e74705SXin Li@interface Test3 : NSObject { 125*67e74705SXin Li id myObj; 126*67e74705SXin Li} 127*67e74705SXin Li- (void)test_self_assign_ivar; 128*67e74705SXin Li@end 129*67e74705SXin Li 130*67e74705SXin Li@implementation Test3 131*67e74705SXin Li- (void)test_self_assign_ivar { 132*67e74705SXin Li CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); 133*67e74705SXin Li CFDateRef date = CFDateCreate(0, t); // no-warning 134*67e74705SXin Li myObj = (id) date; 135*67e74705SXin Li} 136*67e74705SXin Li@end 137*67e74705SXin Li 138*67e74705SXin Li//===------------------------------------------------------------------------------------------===// 139*67e74705SXin Li// <rdar://problem/7257223> (also <rdar://problem/7283470>) - False positive due to not invalidating 140*67e74705SXin Li// the reference count of a tracked region that was itself invalidated. 141*67e74705SXin Li//===------------------------------------------------------------------------------------------===// 142*67e74705SXin Li 143*67e74705SXin Litypedef struct __rdar_7257223 { CFDateRef x; } RDar7257223; 144*67e74705SXin Livoid rdar_7257223_aux(RDar7257223 *p); 145*67e74705SXin Li 146*67e74705SXin LiCFDateRef rdar7257223_Create(void) { 147*67e74705SXin Li RDar7257223 s; 148*67e74705SXin Li CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); 149*67e74705SXin Li s.x = CFDateCreate(0, t); // no-warning 150*67e74705SXin Li rdar_7257223_aux(&s); 151*67e74705SXin Li return s.x; 152*67e74705SXin Li} 153*67e74705SXin Li 154*67e74705SXin LiCFDateRef rdar7257223_Create_2(void) { 155*67e74705SXin Li RDar7257223 s; 156*67e74705SXin Li CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); 157*67e74705SXin Li s.x = CFDateCreate(0, t); // no-warning 158*67e74705SXin Li return s.x; 159*67e74705SXin Li} 160*67e74705SXin Li 161*67e74705SXin Livoid rdar7283470(void) { 162*67e74705SXin Li NSNumber *numbers[] = { 163*67e74705SXin Li [[NSNumber alloc] initWithInt:1], // no-warning 164*67e74705SXin Li [[NSNumber alloc] initWithInt:2], // no-warning 165*67e74705SXin Li [[NSNumber alloc] initWithInt:3], // no-warning 166*67e74705SXin Li [[NSNumber alloc] initWithInt:4], // no-warning 167*67e74705SXin Li [[NSNumber alloc] initWithInt:5] // no-warning 168*67e74705SXin Li }; 169*67e74705SXin Li 170*67e74705SXin Li for (unsigned i = 0 ; i < sizeof(numbers) / sizeof(numbers[0]) ; ++i) 171*67e74705SXin Li [numbers[i] release]; 172*67e74705SXin Li} 173*67e74705SXin Li 174*67e74705SXin Livoid rdar7283470_positive(void) { 175*67e74705SXin Li NSNumber *numbers[] = { 176*67e74705SXin Li [[NSNumber alloc] initWithInt:1], // expected-warning{{leak}} 177*67e74705SXin Li [[NSNumber alloc] initWithInt:2], // expected-warning{{leak}} 178*67e74705SXin Li [[NSNumber alloc] initWithInt:3], // expected-warning{{leak}} 179*67e74705SXin Li [[NSNumber alloc] initWithInt:4], // expected-warning{{leak}} 180*67e74705SXin Li [[NSNumber alloc] initWithInt:5] // expected-warning{{leak}} 181*67e74705SXin Li }; 182*67e74705SXin Li} 183*67e74705SXin Li 184*67e74705SXin Livoid rdar7283470_2(void) { 185*67e74705SXin Li NSNumber *numbers[] = { 186*67e74705SXin Li [[NSNumber alloc] initWithInt:1], // no-warning 187*67e74705SXin Li [[NSNumber alloc] initWithInt:2], // no-warning 188*67e74705SXin Li [[NSNumber alloc] initWithInt:3], // no-warning 189*67e74705SXin Li [[NSNumber alloc] initWithInt:4], // no-warning 190*67e74705SXin Li [[NSNumber alloc] initWithInt:5] // no-warning 191*67e74705SXin Li }; 192*67e74705SXin Li 193*67e74705SXin Li NSArray *s_numbers =[[NSArray alloc] initWithObjects:&numbers[0] count:sizeof(numbers) / sizeof(numbers[0])]; 194*67e74705SXin Li 195*67e74705SXin Li for (unsigned i = 0 ; i < sizeof(numbers) / sizeof(numbers[0]) ; ++i) 196*67e74705SXin Li [numbers[i] release]; 197*67e74705SXin Li 198*67e74705SXin Li [s_numbers release]; 199*67e74705SXin Li} 200*67e74705SXin Li 201*67e74705SXin Livoid rdar7283470_2_positive(void) { 202*67e74705SXin Li NSNumber *numbers[] = { 203*67e74705SXin Li [[NSNumber alloc] initWithInt:1], // no-warning 204*67e74705SXin Li [[NSNumber alloc] initWithInt:2], // no-warning 205*67e74705SXin Li [[NSNumber alloc] initWithInt:3], // no-warning 206*67e74705SXin Li [[NSNumber alloc] initWithInt:4], // no-warning 207*67e74705SXin Li [[NSNumber alloc] initWithInt:5] // no-warning 208*67e74705SXin Li }; 209*67e74705SXin Li 210*67e74705SXin Li NSArray *s_numbers =[[NSArray alloc] initWithObjects: &numbers[0] count:sizeof(numbers) / sizeof(numbers[0])]; // expected-warning{{leak}} 211*67e74705SXin Li 212*67e74705SXin Li for (unsigned i = 0 ; i < sizeof(numbers) / sizeof(numbers[0]) ; ++i) 213*67e74705SXin Li [numbers[i] release]; 214*67e74705SXin Li} 215*67e74705SXin Li 216*67e74705SXin Livoid pr6699(int x) { 217*67e74705SXin Li CFDateRef values[2]; 218*67e74705SXin Li values[0] = values[1] = 0; 219*67e74705SXin Li 220*67e74705SXin Li if (x) { 221*67e74705SXin Li CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); 222*67e74705SXin Li values[1] = CFDateCreate(0, t); 223*67e74705SXin Li } 224*67e74705SXin Li 225*67e74705SXin Li if (values[1]) { 226*67e74705SXin Li // A bug in RegionStore::RemoveDeadBindings caused 'values[1]' to get prematurely 227*67e74705SXin Li // pruned from the store. 228*67e74705SXin Li CFRelease(values[1]); // no-warning 229*67e74705SXin Li } 230*67e74705SXin Li} 231*67e74705SXin Li 232*67e74705SXin Li// <rdar://problem/8261992> Idempotent operation checker false positive with ObjC ivars 233*67e74705SXin Li@interface R8261992 : NSObject { 234*67e74705SXin Li @package int myIvar; 235*67e74705SXin Li} 236*67e74705SXin Li@end 237*67e74705SXin Li 238*67e74705SXin Listatic void R8261992_ChangeMyIvar(R8261992 *tc) { 239*67e74705SXin Li tc->myIvar = 5; 240*67e74705SXin Li} 241*67e74705SXin Li 242*67e74705SXin Livoid R8261992_test(R8261992 *tc) { 243*67e74705SXin Li int temp = tc->myIvar; 244*67e74705SXin Li // The ivar binding for tc->myIvar gets invalidated. 245*67e74705SXin Li R8261992_ChangeMyIvar(tc); 246*67e74705SXin Li tc->myIvar = temp; // no-warning 247*67e74705SXin Li tc = [[R8261992 alloc] init]; 248*67e74705SXin Li temp = tc->myIvar; // no-warning 249*67e74705SXin Li // The ivar binding for tc->myIvar gets invalidated. 250*67e74705SXin Li R8261992_ChangeMyIvar(tc); 251*67e74705SXin Li tc->myIvar = temp; 252*67e74705SXin Li [tc release]; // no-warning 253*67e74705SXin Li // did we analyze this? 254*67e74705SXin Li int *p = 0x0; 255*67e74705SXin Li *p = 0xDEADBEEF; // expected-warning{{null}} 256*67e74705SXin Li} 257*67e74705SXin Li 258