retain-release.m revision 0964a06d5cc1dc36ac5f8c89ba47ec0a47c08bb1
1// RUN: clang -analyze -checker-cfref -verify %s && 2// RUN: clang -analyze -checker-cfref -analyzer-store-region -verify %s 3 4 5//===----------------------------------------------------------------------===// 6// The following code is reduced using delta-debugging from 7// Foundation.h (Mac OS X). 8// 9// It includes the basic definitions for the test cases below. 10// Not including Foundation.h directly makes this test case both svelte and 11// portable to non-Mac platforms. 12//===----------------------------------------------------------------------===// 13 14typedef unsigned int __darwin_natural_t; 15typedef unsigned long UInt32; 16typedef signed long CFIndex; 17typedef const void * CFTypeRef; 18typedef const struct __CFString * CFStringRef; 19typedef const struct __CFAllocator * CFAllocatorRef; 20extern const CFAllocatorRef kCFAllocatorDefault; 21extern CFTypeRef CFRetain(CFTypeRef cf); 22extern void CFRelease(CFTypeRef cf); 23typedef struct { 24} 25CFArrayCallBacks; 26extern const CFArrayCallBacks kCFTypeArrayCallBacks; 27typedef const struct __CFArray * CFArrayRef; 28typedef struct __CFArray * CFMutableArrayRef; 29extern CFMutableArrayRef CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFArrayCallBacks *callBacks); 30extern const void *CFArrayGetValueAtIndex(CFArrayRef theArray, CFIndex idx); 31typedef const struct __CFDictionary * CFDictionaryRef; 32typedef UInt32 CFStringEncoding; 33enum { 34kCFStringEncodingMacRoman = 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 }; 35extern CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding); 36typedef double CFTimeInterval; 37typedef CFTimeInterval CFAbsoluteTime; 38typedef const struct __CFDate * CFDateRef; 39extern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at); 40extern CFAbsoluteTime CFDateGetAbsoluteTime(CFDateRef theDate); 41typedef __darwin_natural_t natural_t; 42typedef natural_t mach_port_name_t; 43typedef mach_port_name_t mach_port_t; 44typedef signed char BOOL; 45typedef struct _NSZone NSZone; 46@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; 47@protocol NSObject - (BOOL)isEqual:(id)object; 48- (id)retain; 49- (oneway void)release; 50@end @protocol NSCopying - (id)copyWithZone:(NSZone *)zone; 51@end @protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; 52@end @interface NSObject <NSObject> { 53} 54@end typedef float CGFloat; 55typedef double NSTimeInterval; 56@interface NSDate : NSObject <NSCopying, NSCoding> - (NSTimeInterval)timeIntervalSinceReferenceDate; 57@end enum { 58NSObjCNoType = 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' } 59__attribute__((deprecated)); 60typedef int kern_return_t; 61typedef kern_return_t mach_error_t; 62typedef mach_port_t io_object_t; 63typedef io_object_t io_service_t; 64typedef struct __DASession * DASessionRef; 65extern DASessionRef DASessionCreate( CFAllocatorRef allocator ); 66typedef struct __DADisk * DADiskRef; 67extern DADiskRef DADiskCreateFromBSDName( CFAllocatorRef allocator, DASessionRef session, const char * name ); 68extern DADiskRef DADiskCreateFromIOMedia( CFAllocatorRef allocator, DASessionRef session, io_service_t media ); 69extern CFDictionaryRef DADiskCopyDescription( DADiskRef disk ); 70extern DADiskRef DADiskCopyWholeDisk( DADiskRef disk ); 71@interface NSAppleEventManager : NSObject { 72} 73@end enum { 74kDAReturnSuccess = 0, kDAReturnError = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x01, kDAReturnBusy = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x02, kDAReturnBadArgument = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x03, kDAReturnExclusiveAccess = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x04, kDAReturnNoResources = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x05, kDAReturnNotFound = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x06, kDAReturnNotMounted = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x07, kDAReturnNotPermitted = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x08, kDAReturnNotPrivileged = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x09, kDAReturnNotReady = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0A, kDAReturnNotWritable = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0B, kDAReturnUnsupported = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0C }; 75typedef mach_error_t DAReturn; 76typedef const struct __DADissenter * DADissenterRef; 77extern DADissenterRef DADissenterCreate( CFAllocatorRef allocator, DAReturn status, CFStringRef string ); 78 79//===----------------------------------------------------------------------===// 80// Test cases. 81//===----------------------------------------------------------------------===// 82 83CFAbsoluteTime f1() { 84 CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); 85 CFDateRef date = CFDateCreate(0, t); 86 CFRetain(date); 87 CFRelease(date); 88 CFDateGetAbsoluteTime(date); // no-warning 89 CFRelease(date); 90 t = CFDateGetAbsoluteTime(date); // expected-warning{{Reference-counted object is used after it is released.}} 91 return t; 92} 93 94CFAbsoluteTime f2() { 95 CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); 96 CFDateRef date = CFDateCreate(0, t); 97 [((NSDate*) date) retain]; 98 CFRelease(date); 99 CFDateGetAbsoluteTime(date); // no-warning 100 [((NSDate*) date) release]; 101 t = CFDateGetAbsoluteTime(date); // expected-warning{{Reference-counted object is used after it is released.}} 102 return t; 103} 104 105 106NSDate* global_x; 107 108// Test to see if we supresss an error when we store the pointer 109// to a global. 110 111CFAbsoluteTime f3() { 112 CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); 113 CFDateRef date = CFDateCreate(0, t); 114 [((NSDate*) date) retain]; 115 CFRelease(date); 116 CFDateGetAbsoluteTime(date); // no-warning 117 global_x = (NSDate*) date; 118 [((NSDate*) date) release]; 119 t = CFDateGetAbsoluteTime(date); // no-warning 120 return t; 121} 122 123//--------------------------------------------------------------------------- 124// Test case 'f4' differs for region store and basic store. See 125// retain-release-region-store.m and retain-release-basic-store.m. 126//--------------------------------------------------------------------------- 127 128// Test a leak. 129 130CFAbsoluteTime f5(int x) { 131 CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); 132 CFDateRef date = CFDateCreate(0, t); 133 134 if (x) 135 CFRelease(date); 136 137 return t; // expected-warning{{leak}} 138} 139 140// Test a leak involving the return. 141 142CFDateRef f6(int x) { 143 CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); 144 CFRetain(date); 145 return date; // expected-warning{{leak}} 146} 147 148// Test a leak involving an overwrite. 149 150CFDateRef f7() { 151 CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); 152 CFRetain(date); //expected-warning{{leak}} 153 date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); 154 return date; 155} 156 157// Generalization of Create rule. MyDateCreate returns a CFXXXTypeRef, and 158// has the word create. 159CFDateRef MyDateCreate(); 160 161CFDateRef f8() { 162 CFDateRef date = MyDateCreate(); 163 CFRetain(date); 164 return date; // expected-warning{{leak}} 165} 166 167CFDateRef f9() { 168 CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); 169 int *p = 0; 170 // test that the checker assumes that CFDateCreate returns a non-null 171 // pointer 172 if (!date) *p = 1; // no-warning 173 return date; 174} 175 176// Handle DiskArbitration API: 177// 178// http://developer.apple.com/DOCUMENTATION/DARWIN/Reference/DiscArbitrationFramework/ 179// 180void f10(io_service_t media, DADiskRef d, CFStringRef s) { 181 DADiskRef disk = DADiskCreateFromBSDName(kCFAllocatorDefault, 0, "hello"); 182 if (disk) NSLog(@"ok"); // expected-warning{{leak}} 183 184 disk = DADiskCreateFromIOMedia(kCFAllocatorDefault, 0, media); 185 if (disk) NSLog(@"ok"); // expected-warning{{leak}} 186 187 CFDictionaryRef dict = DADiskCopyDescription(d); 188 if (dict) NSLog(@"ok"); // expected-warning{{leak}} 189 190 disk = DADiskCopyWholeDisk(d); 191 if (disk) NSLog(@"ok"); // expected-warning{{leak}} 192 193 DADissenterRef dissenter = DADissenterCreate(kCFAllocatorDefault, 194 kDAReturnSuccess, s); 195 if (dissenter) NSLog(@"ok"); // expected-warning{{leak}} 196 197 DASessionRef session = DASessionCreate(kCFAllocatorDefault); 198 if (session) NSLog(@"ok"); // expected-warning{{leak}} 199} 200 201// Test retain/release checker with CFString and CFMutableArray. 202void f11() { 203 // Create the array. 204 CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); 205 206 // Create a string. 207 CFStringRef s1 = CFStringCreateWithCString(0, "hello world", 208 kCFStringEncodingUTF8); 209 210 // Add the string to the array. 211 CFArrayAppendValue(A, s1); 212 213 // Decrement the reference count. 214 CFRelease(s1); // no-warning 215 216 // Get the string. We don't own it. 217 s1 = (CFStringRef) CFArrayGetValueAtIndex(A, 0); 218 219 // Release the array. 220 CFRelease(A); // no-warning 221 222 // Release the string. This is a bug. 223 CFRelease(s1); // expected-warning{{Incorrect decrement of the reference count}} 224} 225 226// PR 3337: Handle functions declared using typedefs. 227typedef CFTypeRef CREATEFUN(); 228CREATEFUN MyCreateFun; 229 230void f12() { 231 CFTypeRef o = MyCreateFun(); // expected-warning {{leak}} 232} 233