1// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease -analyzer-store=basic -fblocks -verify %s 2// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease -analyzer-store=region -fblocks -verify %s 3// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease -analyzer-store=basic -fblocks -verify -x objective-c++ %s 4// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease -analyzer-store=region -fblocks -verify -x objective-c++ %s 5 6#if __has_feature(attribute_ns_returns_retained) 7#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained)) 8#endif 9#if __has_feature(attribute_cf_returns_retained) 10#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained)) 11#endif 12#if __has_feature(attribute_ns_returns_not_retained) 13#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained)) 14#endif 15#if __has_feature(attribute_cf_returns_not_retained) 16#define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained)) 17#endif 18#if __has_feature(attribute_ns_consumes_self) 19#define NS_CONSUMES_SELF __attribute__((ns_consumes_self)) 20#endif 21#if __has_feature(attribute_ns_consumed) 22#define NS_CONSUMED __attribute__((ns_consumed)) 23#endif 24#if __has_feature(attribute_cf_consumed) 25#define CF_CONSUMED __attribute__((cf_consumed)) 26#endif 27 28//===----------------------------------------------------------------------===// 29// The following code is reduced using delta-debugging from Mac OS X headers: 30// 31// #include <Cocoa/Cocoa.h> 32// #include <CoreFoundation/CoreFoundation.h> 33// #include <DiskArbitration/DiskArbitration.h> 34// #include <QuartzCore/QuartzCore.h> 35// #include <Quartz/Quartz.h> 36// #include <IOKit/IOKitLib.h> 37// 38// It includes the basic definitions for the test cases below. 39//===----------------------------------------------------------------------===// 40 41typedef unsigned int __darwin_natural_t; 42typedef unsigned long uintptr_t; 43typedef unsigned int uint32_t; 44typedef unsigned long long uint64_t; 45typedef unsigned int UInt32; 46typedef signed long CFIndex; 47typedef struct { 48 CFIndex location; 49 CFIndex length; 50} CFRange; 51static __inline__ __attribute__((always_inline)) CFRange CFRangeMake(CFIndex loc, CFIndex len) { 52 CFRange range; 53 range.location = loc; 54 range.length = len; 55 return range; 56} 57typedef const void * CFTypeRef; 58typedef const struct __CFString * CFStringRef; 59typedef const struct __CFAllocator * CFAllocatorRef; 60extern const CFAllocatorRef kCFAllocatorDefault; 61extern CFTypeRef CFRetain(CFTypeRef cf); 62extern void CFRelease(CFTypeRef cf); 63typedef struct { 64} 65CFArrayCallBacks; 66extern const CFArrayCallBacks kCFTypeArrayCallBacks; 67typedef const struct __CFArray * CFArrayRef; 68typedef struct __CFArray * CFMutableArrayRef; 69extern CFMutableArrayRef CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFArrayCallBacks *callBacks); 70extern const void *CFArrayGetValueAtIndex(CFArrayRef theArray, CFIndex idx); 71extern void CFArrayAppendValue(CFMutableArrayRef theArray, const void *value); 72typedef struct { 73} 74CFDictionaryKeyCallBacks; 75extern const CFDictionaryKeyCallBacks kCFTypeDictionaryKeyCallBacks; 76typedef struct { 77} 78CFDictionaryValueCallBacks; 79extern const CFDictionaryValueCallBacks kCFTypeDictionaryValueCallBacks; 80typedef const struct __CFDictionary * CFDictionaryRef; 81typedef struct __CFDictionary * CFMutableDictionaryRef; 82extern CFMutableDictionaryRef CFDictionaryCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFDictionaryKeyCallBacks *keyCallBacks, const CFDictionaryValueCallBacks *valueCallBacks); 83typedef UInt32 CFStringEncoding; 84enum { 85kCFStringEncodingMacRoman = 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 }; 86extern CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding); 87typedef double CFTimeInterval; 88typedef CFTimeInterval CFAbsoluteTime; 89extern CFAbsoluteTime CFAbsoluteTimeGetCurrent(void); 90typedef const struct __CFDate * CFDateRef; 91extern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at); 92extern CFAbsoluteTime CFDateGetAbsoluteTime(CFDateRef theDate); 93typedef __darwin_natural_t natural_t; 94typedef natural_t mach_port_name_t; 95typedef mach_port_name_t mach_port_t; 96typedef int kern_return_t; 97typedef kern_return_t mach_error_t; 98enum { 99kCFNumberSInt8Type = 1, kCFNumberSInt16Type = 2, kCFNumberSInt32Type = 3, kCFNumberSInt64Type = 4, kCFNumberFloat32Type = 5, kCFNumberFloat64Type = 6, kCFNumberCharType = 7, kCFNumberShortType = 8, kCFNumberIntType = 9, kCFNumberLongType = 10, kCFNumberLongLongType = 11, kCFNumberFloatType = 12, kCFNumberDoubleType = 13, kCFNumberCFIndexType = 14, kCFNumberNSIntegerType = 15, kCFNumberCGFloatType = 16, kCFNumberMaxType = 16 }; 100typedef CFIndex CFNumberType; 101typedef const struct __CFNumber * CFNumberRef; 102extern CFNumberRef CFNumberCreate(CFAllocatorRef allocator, CFNumberType theType, const void *valuePtr); 103typedef const struct __CFAttributedString *CFAttributedStringRef; 104typedef struct __CFAttributedString *CFMutableAttributedStringRef; 105extern CFAttributedStringRef CFAttributedStringCreate(CFAllocatorRef alloc, CFStringRef str, CFDictionaryRef attributes) ; 106extern CFMutableAttributedStringRef CFAttributedStringCreateMutableCopy(CFAllocatorRef alloc, CFIndex maxLength, CFAttributedStringRef aStr) ; 107extern void CFAttributedStringSetAttribute(CFMutableAttributedStringRef aStr, CFRange range, CFStringRef attrName, CFTypeRef value) ; 108typedef signed char BOOL; 109typedef unsigned long NSUInteger; 110@class NSString, Protocol; 111extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2))); 112typedef struct _NSZone NSZone; 113@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; 114@protocol NSObject 115- (BOOL)isEqual:(id)object; 116- (id)retain; 117- (oneway void)release; 118- (id)autorelease; 119- (id)init; 120@end @protocol NSCopying - (id)copyWithZone:(NSZone *)zone; 121@end @protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; 122@end @protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; 123@end 124@interface NSObject <NSObject> {} 125+ (id)allocWithZone:(NSZone *)zone; 126+ (id)alloc; 127- (void)dealloc; 128@end 129@interface NSObject (NSCoderMethods) 130- (id)awakeAfterUsingCoder:(NSCoder *)aDecoder; 131@end 132extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone); 133typedef struct { 134} 135NSFastEnumerationState; 136@protocol NSFastEnumeration - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len; 137@end @class NSString, NSDictionary; 138@interface NSValue : NSObject <NSCopying, NSCoding> - (void)getValue:(void *)value; 139@end @interface NSNumber : NSValue - (char)charValue; 140- (id)initWithInt:(int)value; 141@end @class NSString; 142@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration> - (NSUInteger)count; 143@end @interface NSArray (NSArrayCreation) + (id)array; 144@end @interface NSAutoreleasePool : NSObject { 145} 146- (void)drain; 147@end extern NSString * const NSBundleDidLoadNotification; 148typedef double NSTimeInterval; 149@interface NSDate : NSObject <NSCopying, NSCoding> - (NSTimeInterval)timeIntervalSinceReferenceDate; 150@end typedef unsigned short unichar; 151@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding> - (NSUInteger)length; 152- ( const char *)UTF8String; 153- (id)initWithUTF8String:(const char *)nullTerminatedCString; 154+ (id)stringWithUTF8String:(const char *)nullTerminatedCString; 155@end @class NSString, NSURL, NSError; 156@interface NSData : NSObject <NSCopying, NSMutableCopying, NSCoding> - (NSUInteger)length; 157+ (id)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length; 158+ (id)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length freeWhenDone:(BOOL)b; 159@end @class NSLocale, NSDate, NSCalendar, NSTimeZone, NSError, NSArray, NSMutableDictionary; 160@interface NSDictionary : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration> - (NSUInteger)count; 161@end @interface NSMutableDictionary : NSDictionary - (void)removeObjectForKey:(id)aKey; 162- (void)setObject:(id)anObject forKey:(id)aKey; 163@end @interface NSMutableDictionary (NSMutableDictionaryCreation) + (id)dictionaryWithCapacity:(NSUInteger)numItems; 164@end typedef double CGFloat; 165struct CGSize { 166}; 167typedef struct CGSize CGSize; 168struct CGRect { 169}; 170typedef struct CGRect CGRect; 171typedef mach_port_t io_object_t; 172typedef char io_name_t[128]; 173typedef io_object_t io_iterator_t; 174typedef io_object_t io_service_t; 175typedef struct IONotificationPort * IONotificationPortRef; 176typedef void (*IOServiceMatchingCallback)( void * refcon, io_iterator_t iterator ); 177io_service_t IOServiceGetMatchingService( mach_port_t masterPort, CFDictionaryRef matching ); 178kern_return_t IOServiceGetMatchingServices( mach_port_t masterPort, CFDictionaryRef matching, io_iterator_t * existing ); 179kern_return_t IOServiceAddNotification( mach_port_t masterPort, const io_name_t notificationType, CFDictionaryRef matching, mach_port_t wakePort, uintptr_t reference, io_iterator_t * notification ) __attribute__((deprecated)); 180kern_return_t IOServiceAddMatchingNotification( IONotificationPortRef notifyPort, const io_name_t notificationType, CFDictionaryRef matching, IOServiceMatchingCallback callback, void * refCon, io_iterator_t * notification ); 181CFMutableDictionaryRef IOServiceMatching( const char * name ); 182CFMutableDictionaryRef IOServiceNameMatching( const char * name ); 183CFMutableDictionaryRef IOBSDNameMatching( mach_port_t masterPort, uint32_t options, const char * bsdName ); 184CFMutableDictionaryRef IOOpenFirmwarePathMatching( mach_port_t masterPort, uint32_t options, const char * path ); 185CFMutableDictionaryRef IORegistryEntryIDMatching( uint64_t entryID ); 186typedef struct __DASession * DASessionRef; 187extern DASessionRef DASessionCreate( CFAllocatorRef allocator ); 188typedef struct __DADisk * DADiskRef; 189extern DADiskRef DADiskCreateFromBSDName( CFAllocatorRef allocator, DASessionRef session, const char * name ); 190extern DADiskRef DADiskCreateFromIOMedia( CFAllocatorRef allocator, DASessionRef session, io_service_t media ); 191extern CFDictionaryRef DADiskCopyDescription( DADiskRef disk ); 192extern DADiskRef DADiskCopyWholeDisk( DADiskRef disk ); 193@interface NSTask : NSObject - (id)init; 194@end typedef struct CGColorSpace *CGColorSpaceRef; 195typedef struct CGImage *CGImageRef; 196typedef struct CGLayer *CGLayerRef; 197@interface NSResponder : NSObject <NSCoding> { 198} 199@end @protocol NSAnimatablePropertyContainer - (id)animator; 200@end extern NSString *NSAnimationTriggerOrderIn ; 201@interface NSView : NSResponder <NSAnimatablePropertyContainer> { 202} 203@end @protocol NSValidatedUserInterfaceItem - (SEL)action; 204@end @protocol NSUserInterfaceValidations - (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)anItem; 205@end @class NSDate, NSDictionary, NSError, NSException, NSNotification; 206@interface NSApplication : NSResponder <NSUserInterfaceValidations> { 207} 208@end enum { 209NSTerminateCancel = 0, NSTerminateNow = 1, NSTerminateLater = 2 }; 210typedef NSUInteger NSApplicationTerminateReply; 211@protocol NSApplicationDelegate <NSObject> @optional - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender; 212@end @class NSAttributedString, NSEvent, NSFont, NSFormatter, NSImage, NSMenu, NSText, NSView, NSTextView; 213@interface NSCell : NSObject <NSCopying, NSCoding> { 214} 215@end @class NSTextField, NSPanel, NSArray, NSWindow, NSImage, NSButton, NSError; 216typedef struct { 217} 218CVTimeStamp; 219@interface CIImage : NSObject <NSCoding, NSCopying> { 220} 221typedef int CIFormat; 222@end enum { 223kDAReturnSuccess = 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 }; 224typedef mach_error_t DAReturn; 225typedef const struct __DADissenter * DADissenterRef; 226extern DADissenterRef DADissenterCreate( CFAllocatorRef allocator, DAReturn status, CFStringRef string ); 227@interface CIContext: NSObject { 228} 229- (CGImageRef)createCGImage:(CIImage *)im fromRect:(CGRect)r; 230- (CGImageRef)createCGImage:(CIImage *)im fromRect:(CGRect)r format:(CIFormat)f colorSpace:(CGColorSpaceRef)cs; 231- (CGLayerRef)createCGLayerWithSize:(CGSize)size info:(CFDictionaryRef)d; 232@end extern NSString* const QCRendererEventKey; 233@protocol QCCompositionRenderer - (NSDictionary*) attributes; 234@end @interface QCRenderer : NSObject <QCCompositionRenderer> { 235} 236- (id) createSnapshotImageOfType:(NSString*)type; 237@end extern NSString* const QCViewDidStartRenderingNotification; 238@interface QCView : NSView <QCCompositionRenderer> { 239} 240- (id) createSnapshotImageOfType:(NSString*)type; 241@end enum { 242ICEXIFOrientation1 = 1, ICEXIFOrientation2 = 2, ICEXIFOrientation3 = 3, ICEXIFOrientation4 = 4, ICEXIFOrientation5 = 5, ICEXIFOrientation6 = 6, ICEXIFOrientation7 = 7, ICEXIFOrientation8 = 8, }; 243@class ICDevice; 244@protocol ICDeviceDelegate <NSObject> @required - (void)didRemoveDevice:(ICDevice*)device; 245@end extern NSString *const ICScannerStatusWarmingUp; 246@class ICScannerDevice; 247@protocol ICScannerDeviceDelegate <ICDeviceDelegate> @optional - (void)scannerDeviceDidBecomeAvailable:(ICScannerDevice*)scanner; 248@end 249 250typedef long unsigned int __darwin_size_t; 251typedef __darwin_size_t size_t; 252typedef unsigned long CFTypeID; 253struct CGPoint { 254 CGFloat x; 255 CGFloat y; 256}; 257typedef struct CGPoint CGPoint; 258typedef struct CGGradient *CGGradientRef; 259typedef uint32_t CGGradientDrawingOptions; 260extern CFTypeID CGGradientGetTypeID(void); 261extern CGGradientRef CGGradientCreateWithColorComponents(CGColorSpaceRef 262 space, const CGFloat components[], const CGFloat locations[], size_t count); 263extern CGGradientRef CGGradientCreateWithColors(CGColorSpaceRef space, 264 CFArrayRef colors, const CGFloat locations[]); 265extern CGGradientRef CGGradientRetain(CGGradientRef gradient); 266extern void CGGradientRelease(CGGradientRef gradient); 267typedef struct CGContext *CGContextRef; 268extern void CGContextDrawLinearGradient(CGContextRef context, 269 CGGradientRef gradient, CGPoint startPoint, CGPoint endPoint, 270 CGGradientDrawingOptions options); 271extern CGColorSpaceRef CGColorSpaceCreateDeviceRGB(void); 272 273//===----------------------------------------------------------------------===// 274// Test cases. 275//===----------------------------------------------------------------------===// 276 277CFAbsoluteTime f1() { 278 CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); 279 CFDateRef date = CFDateCreate(0, t); 280 CFRetain(date); 281 CFRelease(date); 282 CFDateGetAbsoluteTime(date); // no-warning 283 CFRelease(date); 284 t = CFDateGetAbsoluteTime(date); // expected-warning{{Reference-counted object is used after it is released}} 285 return t; 286} 287 288CFAbsoluteTime f2() { 289 CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); 290 CFDateRef date = CFDateCreate(0, t); 291 [((NSDate*) date) retain]; 292 CFRelease(date); 293 CFDateGetAbsoluteTime(date); // no-warning 294 [((NSDate*) date) release]; 295 t = CFDateGetAbsoluteTime(date); // expected-warning{{Reference-counted object is used after it is released}} 296 return t; 297} 298 299 300NSDate* global_x; 301 302// Test to see if we supresss an error when we store the pointer 303// to a global. 304 305CFAbsoluteTime f3() { 306 CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); 307 CFDateRef date = CFDateCreate(0, t); 308 [((NSDate*) date) retain]; 309 CFRelease(date); 310 CFDateGetAbsoluteTime(date); // no-warning 311 global_x = (NSDate*) date; 312 [((NSDate*) date) release]; 313 t = CFDateGetAbsoluteTime(date); // no-warning 314 return t; 315} 316 317//--------------------------------------------------------------------------- 318// Test case 'f4' differs for region store and basic store. See 319// retain-release-region-store.m and retain-release-basic-store.m. 320//--------------------------------------------------------------------------- 321 322// Test a leak. 323 324CFAbsoluteTime f5(int x) { 325 CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); 326 CFDateRef date = CFDateCreate(0, t); // expected-warning{{leak}} 327 328 if (x) 329 CFRelease(date); 330 331 return t; 332} 333 334// Test a leak involving the return. 335 336CFDateRef f6(int x) { 337 CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); // expected-warning{{leak}} 338 CFRetain(date); 339 return date; 340} 341 342// Test a leak involving an overwrite. 343 344CFDateRef f7() { 345 CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); //expected-warning{{leak}} 346 CFRetain(date); 347 date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); // expected-warning {{leak}} 348 return date; 349} 350 351// Generalization of Create rule. MyDateCreate returns a CFXXXTypeRef, and 352// has the word create. 353CFDateRef MyDateCreate(); 354 355CFDateRef f8() { 356 CFDateRef date = MyDateCreate(); // expected-warning{{leak}} 357 CFRetain(date); 358 return date; 359} 360 361__attribute__((cf_returns_retained)) CFDateRef f9() { 362 CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); // no-warning 363 int *p = 0; 364 // When allocations fail, CFDateCreate can return null. 365 if (!date) *p = 1; // expected-warning{{null}} 366 return date; 367} 368 369// Handle DiskArbitration API: 370// 371// http://developer.apple.com/DOCUMENTATION/DARWIN/Reference/DiscArbitrationFramework/ 372// 373void f10(io_service_t media, DADiskRef d, CFStringRef s) { 374 DADiskRef disk = DADiskCreateFromBSDName(kCFAllocatorDefault, 0, "hello"); // expected-warning{{leak}} 375 if (disk) NSLog(@"ok"); 376 377 disk = DADiskCreateFromIOMedia(kCFAllocatorDefault, 0, media); // expected-warning{{leak}} 378 if (disk) NSLog(@"ok"); 379 380 CFDictionaryRef dict = DADiskCopyDescription(d); // expected-warning{{leak}} 381 if (dict) NSLog(@"ok"); 382 383 disk = DADiskCopyWholeDisk(d); // expected-warning{{leak}} 384 if (disk) NSLog(@"ok"); 385 386 DADissenterRef dissenter = DADissenterCreate(kCFAllocatorDefault, // expected-warning{{leak}} 387 kDAReturnSuccess, s); 388 if (dissenter) NSLog(@"ok"); 389 390 DASessionRef session = DASessionCreate(kCFAllocatorDefault); // expected-warning{{leak}} 391 if (session) NSLog(@"ok"); 392} 393 394// Test retain/release checker with CFString and CFMutableArray. 395void f11() { 396 // Create the array. 397 CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); 398 399 // Create a string. 400 CFStringRef s1 = CFStringCreateWithCString(0, "hello world", 401 kCFStringEncodingUTF8); 402 403 // Add the string to the array. 404 CFArrayAppendValue(A, s1); 405 406 // Decrement the reference count. 407 CFRelease(s1); // no-warning 408 409 // Get the string. We don't own it. 410 s1 = (CFStringRef) CFArrayGetValueAtIndex(A, 0); 411 412 // Release the array. 413 CFRelease(A); // no-warning 414 415 // Release the string. This is a bug. 416 CFRelease(s1); // expected-warning{{Incorrect decrement of the reference count}} 417} 418 419// PR 3337: Handle functions declared using typedefs. 420typedef CFTypeRef CREATEFUN(); 421CREATEFUN MyCreateFun; 422 423void f12() { 424 CFTypeRef o = MyCreateFun(); // expected-warning {{leak}} 425} 426 427void f13_autorelease() { 428 CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning 429 [(id) A autorelease]; // no-warning 430} 431 432void f13_autorelease_b() { 433 CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); 434 [(id) A autorelease]; 435 [(id) A autorelease]; // expected-warning{{Object sent -autorelease too many times}} 436} 437 438CFMutableArrayRef f13_autorelease_c() { 439 CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); 440 [(id) A autorelease]; 441 [(id) A autorelease]; 442 return A; // expected-warning{{Object sent -autorelease too many times}} 443} 444 445CFMutableArrayRef f13_autorelease_d() { 446 CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); 447 [(id) A autorelease]; 448 [(id) A autorelease]; 449 CFMutableArrayRef B = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{Object sent -autorelease too many times}} 450 CFRelease(B); // no-warning 451 while (1) {} 452} 453 454 455// This case exercises the logic where the leak site is the same as the allocation site. 456void f14_leakimmediately() { 457 CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{leak}} 458} 459 460// Test that we track an allocated object beyond the point where the *name* 461// of the variable storing the reference is no longer live. 462void f15() { 463 // Create the array. 464 CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); 465 CFMutableArrayRef *B = &A; 466 // At this point, the name 'A' is no longer live. 467 CFRelease(*B); // no-warning 468} 469 470// Test when we pass NULL to CFRetain/CFRelease. 471void f16(int x, CFTypeRef p) { 472 if (p) 473 return; 474 475 if (x) { 476 CFRelease(p); // expected-warning{{Null pointer argument in call to CFRelease}} 477 } 478 else { 479 CFRetain(p); // expected-warning{{Null pointer argument in call to CFRetain}} 480 } 481} 482 483// Test that an object is non-null after being CFRetained/CFReleased. 484void f17(int x, CFTypeRef p) { 485 if (x) { 486 CFRelease(p); 487 if (!p) 488 CFRelease(0); // no-warning 489 } 490 else { 491 CFRetain(p); 492 if (!p) 493 CFRetain(0); // no-warning 494 } 495} 496 497// Test basic tracking of ivars associated with 'self'. For the retain/release 498// checker we currently do not want to flag leaks associated with stores 499// of tracked objects to ivars. 500@interface SelfIvarTest : NSObject { 501 id myObj; 502} 503- (void)test_self_tracking; 504@end 505 506@implementation SelfIvarTest 507- (void)test_self_tracking { 508 myObj = (id) CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning 509} 510@end 511 512// Test return of non-owned objects in contexts where an owned object 513// is expected. 514@interface TestReturnNotOwnedWhenExpectedOwned 515- (NSString*)newString; 516@end 517 518@implementation TestReturnNotOwnedWhenExpectedOwned 519- (NSString*)newString { 520 NSString *s = [NSString stringWithUTF8String:"hello"]; 521 return s; // expected-warning{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} 522} 523@end 524 525// <rdar://problem/6659160> 526int isFoo(char c); 527 528static void rdar_6659160(char *inkind, char *inname) 529{ 530 // We currently expect that [NSObject alloc] cannot fail. This 531 // will be a toggled flag in the future. It can indeed return null, but 532 // Cocoa programmers generally aren't expected to reason about out-of-memory 533 // conditions. 534 NSString *kind = [[NSString alloc] initWithUTF8String:inkind]; // expected-warning{{leak}} 535 536 // We do allow stringWithUTF8String to fail. This isn't really correct, as 537 // far as returning 0. In most error conditions it will throw an exception. 538 // If allocation fails it could return 0, but again this 539 // isn't expected. 540 NSString *name = [NSString stringWithUTF8String:inname]; 541 if(!name) 542 return; 543 544 const char *kindC = 0; 545 const char *nameC = 0; 546 547 // In both cases, we cannot reach a point down below where we 548 // dereference kindC or nameC with either being null. This is because 549 // we assume that [NSObject alloc] doesn't fail and that we have the guard 550 // up above. 551 552 if(kind) 553 kindC = [kind UTF8String]; 554 if(name) 555 nameC = [name UTF8String]; 556 if(!isFoo(kindC[0])) // expected-warning{{null}} 557 return; 558 if(!isFoo(nameC[0])) // no-warning 559 return; 560 561 [kind release]; 562 [name release]; // expected-warning{{Incorrect decrement of the reference count}} 563} 564 565// PR 3677 - 'allocWithZone' should be treated as following the Cocoa naming 566// conventions with respect to 'return'ing ownership. 567@interface PR3677: NSObject @end 568@implementation PR3677 569+ (id)allocWithZone:(NSZone *)inZone { 570 return [super allocWithZone:inZone]; // no-warning 571} 572@end 573 574// PR 3820 - Reason about calls to -dealloc 575void pr3820_DeallocInsteadOfRelease(void) 576{ 577 id foo = [[NSString alloc] init]; // no-warning 578 [foo dealloc]; 579 // foo is not leaked, since it has been deallocated. 580} 581 582void pr3820_ReleaseAfterDealloc(void) 583{ 584 id foo = [[NSString alloc] init]; 585 [foo dealloc]; 586 [foo release]; // expected-warning{{used after it is release}} 587 // NSInternalInconsistencyException: message sent to deallocated object 588} 589 590void pr3820_DeallocAfterRelease(void) 591{ 592 NSLog(@"\n\n[%s]", __FUNCTION__); 593 id foo = [[NSString alloc] init]; 594 [foo release]; 595 [foo dealloc]; // expected-warning{{used after it is released}} 596 // message sent to released object 597} 598 599// From <rdar://problem/6704930>. The problem here is that 'length' binds to 600// '($0 - 1)' after '--length', but SimpleConstraintManager doesn't know how to 601// reason about '($0 - 1) > constant'. As a temporary hack, we drop the value 602// of '($0 - 1)' and conjure a new symbol. 603void rdar6704930(unsigned char *s, unsigned int length) { 604 NSString* name = 0; 605 if (s != 0) { 606 if (length > 0) { 607 while (length > 0) { 608 if (*s == ':') { 609 ++s; 610 --length; 611 name = [[NSString alloc] init]; // no-warning 612 break; 613 } 614 ++s; 615 --length; 616 } 617 if ((length == 0) && (name != 0)) { 618 [name release]; 619 name = 0; 620 } 621 if (length == 0) { // no ':' found -> use it all as name 622 name = [[NSString alloc] init]; // no-warning 623 } 624 } 625 } 626 627 if (name != 0) { 628 [name release]; 629 } 630} 631 632//===----------------------------------------------------------------------===// 633// <rdar://problem/6833332> 634// One build of the analyzer accidentally stopped tracking the allocated 635// object after the 'retain'. 636//===----------------------------------------------------------------------===// 637 638@interface rdar_6833332 : NSObject <NSApplicationDelegate> { 639 NSWindow *window; 640} 641@property (nonatomic, retain) NSWindow *window; 642@end 643 644@implementation rdar_6833332 645@synthesize window; 646- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { 647 NSMutableDictionary *dict = [[NSMutableDictionary dictionaryWithCapacity:4] retain]; // expected-warning{{leak}} 648 649 [dict setObject:@"foo" forKey:@"bar"]; 650 651 NSLog(@"%@", dict); 652} 653- (void)dealloc { 654 [window release]; 655 [super dealloc]; 656} 657@end 658 659//===----------------------------------------------------------------------===// 660// <rdar://problem/6257780> clang checker fails to catch use-after-release 661//===----------------------------------------------------------------------===// 662 663int rdar_6257780_Case1() { 664 NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 665 NSArray *array = [NSArray array]; 666 [array release]; // expected-warning{{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} 667 [pool drain]; 668 return 0; 669} 670 671//===----------------------------------------------------------------------===// 672// <rdar://problem/6866843> Checker should understand new/setObject:/release constructs 673//===----------------------------------------------------------------------===// 674 675void rdar_6866843() { 676 NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 677 NSMutableDictionary* dictionary = [[NSMutableDictionary alloc] init]; 678 NSArray* array = [[NSArray alloc] init]; 679 [dictionary setObject:array forKey:@"key"]; 680 [array release]; 681 // Using 'array' here should be fine 682 NSLog(@"array = %@\n", array); // no-warning 683 // Now the array is released 684 [dictionary release]; 685 [pool drain]; 686} 687 688 689//===----------------------------------------------------------------------===// 690// <rdar://problem/6877235> Classes typedef-ed to CF objects should get the same treatment as CF objects 691//===----------------------------------------------------------------------===// 692 693typedef CFTypeRef OtherRef; 694 695@interface RDar6877235 : NSObject {} 696- (CFTypeRef)_copyCFTypeRef; 697- (OtherRef)_copyOtherRef; 698@end 699 700@implementation RDar6877235 701- (CFTypeRef)_copyCFTypeRef { 702 return [[NSString alloc] init]; // no-warning 703} 704- (OtherRef)_copyOtherRef { 705 return [[NSString alloc] init]; // no-warning 706} 707@end 708 709//===----------------------------------------------------------------------===// 710//<rdar://problem/6320065> false positive - init method returns an object 711// owned by caller 712//===----------------------------------------------------------------------===// 713 714@interface RDar6320065 : NSObject { 715 NSString *_foo; 716} 717- (id)initReturningNewClass; 718- (id)_initReturningNewClassBad; 719- (id)initReturningNewClassBad2; 720@end 721 722@interface RDar6320065Subclass : RDar6320065 723@end 724 725@implementation RDar6320065 726- (id)initReturningNewClass { 727 [self release]; 728 self = [[RDar6320065Subclass alloc] init]; // no-warning 729 return self; 730} 731- (id)_initReturningNewClassBad { 732 [self release]; 733 [[RDar6320065Subclass alloc] init]; // expected-warning {{leak}} 734 return self; 735} 736- (id)initReturningNewClassBad2 { 737 [self release]; 738 self = [[RDar6320065Subclass alloc] init]; 739 return [self autorelease]; // expected-warning{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} 740} 741 742@end 743 744@implementation RDar6320065Subclass 745@end 746 747int RDar6320065_test() { 748 RDar6320065 *test = [[RDar6320065 alloc] init]; // no-warning 749 [test release]; 750 return 0; 751} 752 753//===----------------------------------------------------------------------===// 754// <rdar://problem/7129086> -awakeAfterUsingCoder: returns an owned object 755// and claims the receiver 756//===----------------------------------------------------------------------===// 757 758@interface RDar7129086 : NSObject {} @end 759@implementation RDar7129086 760- (id)awakeAfterUsingCoder:(NSCoder *)aDecoder { 761 [self release]; // no-warning 762 return [NSString alloc]; // no-warning 763} 764@end 765 766//===----------------------------------------------------------------------===// 767// <rdar://problem/6859457> [NSData dataWithBytesNoCopy] does not return a 768// retained object 769//===----------------------------------------------------------------------===// 770 771@interface RDar6859457 : NSObject {} 772- (NSString*) NoCopyString; 773- (NSString*) noCopyString; 774@end 775 776@implementation RDar6859457 777- (NSString*) NoCopyString { return [[NSString alloc] init]; } // expected-warning{{leak}} 778- (NSString*) noCopyString { return [[NSString alloc] init]; } // expected-warning{{leak}} 779@end 780 781void test_RDar6859457(RDar6859457 *x, void *bytes, NSUInteger dataLength) { 782 [x NoCopyString]; // no-warning 783 [x noCopyString]; // no-warning 784 [NSData dataWithBytesNoCopy:bytes length:dataLength]; // no-warning 785 [NSData dataWithBytesNoCopy:bytes length:dataLength freeWhenDone:1]; // no-warning 786} 787 788//===----------------------------------------------------------------------===// 789// PR 4230 - an autorelease pool is not necessarily leaked during a premature 790// return 791//===----------------------------------------------------------------------===// 792 793static void PR4230(void) 794{ 795 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // no-warning 796 NSString *object = [[[NSString alloc] init] autorelease]; // no-warning 797 return; 798} 799 800//===----------------------------------------------------------------------===// 801// Method name that has a null IdentifierInfo* for its first selector slot. 802// This test just makes sure that we handle it. 803//===----------------------------------------------------------------------===// 804 805@interface TestNullIdentifier 806@end 807 808@implementation TestNullIdentifier 809+ (id):(int)x, ... { 810 return [[NSString alloc] init]; // expected-warning{{leak}} 811} 812@end 813 814//===----------------------------------------------------------------------===// 815// <rdar://problem/6893565> don't flag leaks for return types that cannot be 816// determined to be CF types 817//===----------------------------------------------------------------------===// 818 819// We don't know if 'struct s6893565' represents a Core Foundation type, so 820// we shouldn't emit an error here. 821typedef struct s6893565* TD6893565; 822 823@interface RDar6893565 {} 824-(TD6893565)newThing; 825@end 826 827@implementation RDar6893565 828-(TD6893565)newThing { 829 return (TD6893565) [[NSString alloc] init]; // no-warning 830} 831@end 832 833//===----------------------------------------------------------------------===// 834// <rdar://problem/6902710> clang: false positives w/QC and CoreImage methods 835//===----------------------------------------------------------------------===// 836 837void rdar6902710(QCView *view, QCRenderer *renderer, CIContext *context, 838 NSString *str, CIImage *img, CGRect rect, 839 CIFormat form, CGColorSpaceRef cs) { 840 [view createSnapshotImageOfType:str]; // expected-warning{{leak}} 841 [renderer createSnapshotImageOfType:str]; // expected-warning{{leak}} 842 [context createCGImage:img fromRect:rect]; // expected-warning{{leak}} 843 [context createCGImage:img fromRect:rect format:form colorSpace:cs]; // expected-warning{{leak}} 844} 845 846//===----------------------------------------------------------------------===// 847// <rdar://problem/6945561> -[CIContext createCGLayerWithSize:info:] 848// misinterpreted by clang scan-build 849//===----------------------------------------------------------------------===// 850 851void rdar6945561(CIContext *context, CGSize size, CFDictionaryRef d) { 852 [context createCGLayerWithSize:size info:d]; // expected-warning{{leak}} 853} 854 855//===----------------------------------------------------------------------===// 856// <rdar://problem/6961230> add knowledge of IOKit functions to retain/release 857// checker 858//===----------------------------------------------------------------------===// 859 860void IOBSDNameMatching_wrapper(mach_port_t masterPort, uint32_t options, const char * bsdName) { 861 IOBSDNameMatching(masterPort, options, bsdName); // expected-warning{{leak}} 862} 863 864void IOServiceMatching_wrapper(const char * name) { 865 IOServiceMatching(name); // expected-warning{{leak}} 866} 867 868void IOServiceNameMatching_wrapper(const char * name) { 869 IOServiceNameMatching(name); // expected-warning{{leak}} 870} 871 872CF_RETURNS_RETAINED CFDictionaryRef CreateDict(); 873 874void IOServiceAddNotification_wrapper(mach_port_t masterPort, const io_name_t notificationType, 875 mach_port_t wakePort, uintptr_t reference, io_iterator_t * notification ) { 876 877 CFDictionaryRef matching = CreateDict(); 878 CFRelease(matching); 879 IOServiceAddNotification(masterPort, notificationType, matching, // expected-warning{{used after it is released}} expected-warning{{deprecated}} 880 wakePort, reference, notification); 881} 882 883void IORegistryEntryIDMatching_wrapper(uint64_t entryID ) { 884 IORegistryEntryIDMatching(entryID); // expected-warning{{leak}} 885} 886 887void IOOpenFirmwarePathMatching_wrapper(mach_port_t masterPort, uint32_t options, 888 const char * path) { 889 IOOpenFirmwarePathMatching(masterPort, options, path); // expected-warning{{leak}} 890} 891 892void IOServiceGetMatchingService_wrapper(mach_port_t masterPort) { 893 CFDictionaryRef matching = CreateDict(); 894 IOServiceGetMatchingService(masterPort, matching); 895 CFRelease(matching); // expected-warning{{used after it is released}} 896} 897 898void IOServiceGetMatchingServices_wrapper(mach_port_t masterPort, io_iterator_t *existing) { 899 CFDictionaryRef matching = CreateDict(); 900 IOServiceGetMatchingServices(masterPort, matching, existing); 901 CFRelease(matching); // expected-warning{{used after it is released}} 902} 903 904void IOServiceAddMatchingNotification_wrapper(IONotificationPortRef notifyPort, const io_name_t notificationType, 905 IOServiceMatchingCallback callback, void * refCon, io_iterator_t * notification) { 906 907 CFDictionaryRef matching = CreateDict(); 908 IOServiceAddMatchingNotification(notifyPort, notificationType, matching, callback, refCon, notification); 909 CFRelease(matching); // expected-warning{{used after it is released}} 910} 911 912//===----------------------------------------------------------------------===// 913// Test of handling objects whose references "escape" to containers. 914//===----------------------------------------------------------------------===// 915 916void CFDictionaryAddValue(CFMutableDictionaryRef, void *, void *); 917 918// <rdar://problem/6539791> 919void rdar_6539791(CFMutableDictionaryRef y, void* key, void* val_key) { 920 CFMutableDictionaryRef x = CFDictionaryCreateMutable(kCFAllocatorDefault, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); 921 CFDictionaryAddValue(y, key, x); 922 CFRelease(x); // the dictionary keeps a reference, so the object isn't deallocated yet 923 signed z = 1; 924 CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); 925 if (value) { 926 CFDictionaryAddValue(x, val_key, (void*)value); // no-warning 927 CFRelease(value); 928 CFDictionaryAddValue(y, val_key, (void*)value); // no-warning 929 } 930} 931 932// <rdar://problem/6560661> 933// Same issue, except with "AppendValue" functions. 934void rdar_6560661(CFMutableArrayRef x) { 935 signed z = 1; 936 CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); 937 // CFArrayAppendValue keeps a reference to value. 938 CFArrayAppendValue(x, value); 939 CFRelease(value); 940 CFRetain(value); 941 CFRelease(value); // no-warning 942} 943 944// <rdar://problem/7152619> 945// Same issue, excwept with "CFAttributeStringSetAttribute". 946void rdar_7152619(CFStringRef str) { 947 CFAttributedStringRef string = CFAttributedStringCreate(kCFAllocatorDefault, str, 0); 948 CFMutableAttributedStringRef attrString = CFAttributedStringCreateMutableCopy(kCFAllocatorDefault, 100, string); 949 CFRelease(string); 950 NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}} 951 CFAttributedStringSetAttribute(attrString, CFRangeMake(0, 1), str, number); 952 [number release]; 953 [number retain]; 954 CFRelease(attrString); 955} 956 957//===----------------------------------------------------------------------===// 958// Test of handling CGGradientXXX functions. 959//===----------------------------------------------------------------------===// 960 961void rdar_7184450(CGContextRef myContext, CGFloat x, CGPoint myStartPoint, 962 CGPoint myEndPoint) { 963 size_t num_locations = 6; 964 CGFloat locations[6] = { 0.0, 0.265, 0.28, 0.31, 0.36, 1.0 }; 965 CGFloat components[28] = { 239.0/256.0, 167.0/256.0, 170.0/256.0, 966 x, // Start color 967 207.0/255.0, 39.0/255.0, 39.0/255.0, x, 968 147.0/255.0, 21.0/255.0, 22.0/255.0, x, 969 175.0/255.0, 175.0/255.0, 175.0/255.0, x, 970 255.0/255.0,255.0/255.0, 255.0/255.0, x, 971 255.0/255.0,255.0/255.0, 255.0/255.0, x 972 }; // End color 973 974 CGGradientRef myGradient = 975 CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), // expected-warning{{leak}} 976 components, locations, num_locations); 977 978 CGContextDrawLinearGradient(myContext, myGradient, myStartPoint, myEndPoint, 979 0); 980 CGGradientRelease(myGradient); 981} 982 983void rdar_7184450_pos(CGContextRef myContext, CGFloat x, CGPoint myStartPoint, 984 CGPoint myEndPoint) { 985 size_t num_locations = 6; 986 CGFloat locations[6] = { 0.0, 0.265, 0.28, 0.31, 0.36, 1.0 }; 987 CGFloat components[28] = { 239.0/256.0, 167.0/256.0, 170.0/256.0, 988 x, // Start color 989 207.0/255.0, 39.0/255.0, 39.0/255.0, x, 990 147.0/255.0, 21.0/255.0, 22.0/255.0, x, 991 175.0/255.0, 175.0/255.0, 175.0/255.0, x, 992 255.0/255.0,255.0/255.0, 255.0/255.0, x, 993 255.0/255.0,255.0/255.0, 255.0/255.0, x 994 }; // End color 995 996 CGGradientRef myGradient = 997 CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), components, locations, num_locations); // expected-warning 2 {{leak}} 998 999 CGContextDrawLinearGradient(myContext, myGradient, myStartPoint, myEndPoint, 1000 0); 1001} 1002 1003//===----------------------------------------------------------------------===// 1004// <rdar://problem/7299394> clang false positive: retained instance passed to 1005// thread in pthread_create marked as leak 1006// 1007// Until we have full IPA, the analyzer should stop tracking the reference 1008// count of objects passed to pthread_create. 1009// 1010//===----------------------------------------------------------------------===// 1011 1012struct _opaque_pthread_t {}; 1013struct _opaque_pthread_attr_t {}; 1014typedef struct _opaque_pthread_t *__darwin_pthread_t; 1015typedef struct _opaque_pthread_attr_t __darwin_pthread_attr_t; 1016typedef __darwin_pthread_t pthread_t; 1017typedef __darwin_pthread_attr_t pthread_attr_t; 1018 1019int pthread_create(pthread_t *, const pthread_attr_t *, 1020 void *(*)(void *), void *); 1021 1022void *rdar_7299394_start_routine(void *p) { 1023 [((id) p) release]; 1024 return 0; 1025} 1026void rdar_7299394(pthread_attr_t *attr, pthread_t *thread, void *args) { 1027 NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning 1028 pthread_create(thread, attr, rdar_7299394_start_routine, number); 1029} 1030void rdar_7299394_positive(pthread_attr_t *attr, pthread_t *thread) { 1031 NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}} 1032} 1033 1034//===----------------------------------------------------------------------===// 1035// <rdar://problem/7283567> False leak associated with call to 1036// CVPixelBufferCreateWithBytes () 1037// 1038// According to the Core Video Reference (ADC), CVPixelBufferCreateWithBytes and 1039// CVPixelBufferCreateWithPlanarBytes can release (via a callback) the 1040// pixel buffer object. These test cases show how the analyzer stops tracking 1041// the reference count for the objects passed for this argument. This 1042// could be made smarter. 1043//===----------------------------------------------------------------------===// 1044 1045typedef int int32_t; 1046typedef UInt32 FourCharCode; 1047typedef FourCharCode OSType; 1048typedef uint64_t CVOptionFlags; 1049typedef int32_t CVReturn; 1050typedef struct __CVBuffer *CVBufferRef; 1051typedef CVBufferRef CVImageBufferRef; 1052typedef CVImageBufferRef CVPixelBufferRef; 1053typedef void (*CVPixelBufferReleaseBytesCallback)( void *releaseRefCon, const void *baseAddress ); 1054 1055extern CVReturn CVPixelBufferCreateWithBytes(CFAllocatorRef allocator, 1056 size_t width, 1057 size_t height, 1058 OSType pixelFormatType, 1059 void *baseAddress, 1060 size_t bytesPerRow, 1061 CVPixelBufferReleaseBytesCallback releaseCallback, 1062 void *releaseRefCon, 1063 CFDictionaryRef pixelBufferAttributes, 1064 CVPixelBufferRef *pixelBufferOut) ; 1065 1066typedef void (*CVPixelBufferReleasePlanarBytesCallback)( void *releaseRefCon, const void *dataPtr, size_t dataSize, size_t numberOfPlanes, const void *planeAddresses[] ); 1067 1068extern CVReturn CVPixelBufferCreateWithPlanarBytes(CFAllocatorRef allocator, 1069 size_t width, 1070 size_t height, 1071 OSType pixelFormatType, 1072 void *dataPtr, 1073 size_t dataSize, 1074 size_t numberOfPlanes, 1075 void *planeBaseAddress[], 1076 size_t planeWidth[], 1077 size_t planeHeight[], 1078 size_t planeBytesPerRow[], 1079 CVPixelBufferReleasePlanarBytesCallback releaseCallback, 1080 void *releaseRefCon, 1081 CFDictionaryRef pixelBufferAttributes, 1082 CVPixelBufferRef *pixelBufferOut) ; 1083 1084extern CVReturn CVPixelBufferCreateWithBytes(CFAllocatorRef allocator, 1085 size_t width, 1086 size_t height, 1087 OSType pixelFormatType, 1088 void *baseAddress, 1089 size_t bytesPerRow, 1090 CVPixelBufferReleaseBytesCallback releaseCallback, 1091 void *releaseRefCon, 1092 CFDictionaryRef pixelBufferAttributes, 1093 CVPixelBufferRef *pixelBufferOut) ; 1094 1095CVReturn rdar_7283567(CFAllocatorRef allocator, size_t width, size_t height, 1096 OSType pixelFormatType, void *baseAddress, 1097 size_t bytesPerRow, 1098 CVPixelBufferReleaseBytesCallback releaseCallback, 1099 CFDictionaryRef pixelBufferAttributes, 1100 CVPixelBufferRef *pixelBufferOut) { 1101 1102 // For the allocated object, it doesn't really matter what type it is 1103 // for the purpose of this test. All we want to show is that 1104 // this is freed later by the callback. 1105 NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning 1106 1107 return CVPixelBufferCreateWithBytes(allocator, width, height, pixelFormatType, 1108 baseAddress, bytesPerRow, releaseCallback, 1109 number, // potentially released by callback 1110 pixelBufferAttributes, pixelBufferOut) ; 1111} 1112 1113CVReturn rdar_7283567_2(CFAllocatorRef allocator, size_t width, size_t height, 1114 OSType pixelFormatType, void *dataPtr, size_t dataSize, 1115 size_t numberOfPlanes, void *planeBaseAddress[], 1116 size_t planeWidth[], size_t planeHeight[], size_t planeBytesPerRow[], 1117 CVPixelBufferReleasePlanarBytesCallback releaseCallback, 1118 CFDictionaryRef pixelBufferAttributes, 1119 CVPixelBufferRef *pixelBufferOut) { 1120 1121 // For the allocated object, it doesn't really matter what type it is 1122 // for the purpose of this test. All we want to show is that 1123 // this is freed later by the callback. 1124 NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning 1125 1126 return CVPixelBufferCreateWithPlanarBytes(allocator, 1127 width, height, pixelFormatType, dataPtr, dataSize, 1128 numberOfPlanes, planeBaseAddress, planeWidth, 1129 planeHeight, planeBytesPerRow, releaseCallback, 1130 number, // potentially released by callback 1131 pixelBufferAttributes, pixelBufferOut) ; 1132} 1133 1134//===----------------------------------------------------------------------===// 1135// <rdar://problem/7358899> False leak associated with 1136// CGBitmapContextCreateWithData 1137//===----------------------------------------------------------------------===// 1138typedef uint32_t CGBitmapInfo; 1139typedef void (*CGBitmapContextReleaseDataCallback)(void *releaseInfo, void *data); 1140 1141CGContextRef CGBitmapContextCreateWithData(void *data, 1142 size_t width, size_t height, size_t bitsPerComponent, 1143 size_t bytesPerRow, CGColorSpaceRef space, CGBitmapInfo bitmapInfo, 1144 CGBitmapContextReleaseDataCallback releaseCallback, void *releaseInfo); 1145 1146void rdar_7358899(void *data, 1147 size_t width, size_t height, size_t bitsPerComponent, 1148 size_t bytesPerRow, CGColorSpaceRef space, CGBitmapInfo bitmapInfo, 1149 CGBitmapContextReleaseDataCallback releaseCallback) { 1150 1151 // For the allocated object, it doesn't really matter what type it is 1152 // for the purpose of this test. All we want to show is that 1153 // this is freed later by the callback. 1154 NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning 1155 1156 CGBitmapContextCreateWithData(data, width, height, bitsPerComponent, // expected-warning{{leak}} 1157 bytesPerRow, space, bitmapInfo, releaseCallback, number); 1158} 1159 1160//===----------------------------------------------------------------------===// 1161// <rdar://problem/7265711> allow 'new', 'copy', 'alloc', 'init' prefix to 1162// start before '_' when determining Cocoa fundamental rule 1163// 1164// Previously the retain/release checker just skipped prefixes before the 1165// first '_' entirely. Now the checker honors the prefix if it results in a 1166// recognizable naming convention (e.g., 'new', 'init'). 1167//===----------------------------------------------------------------------===// 1168 1169@interface RDar7265711 {} 1170- (id) new_stuff; 1171@end 1172 1173void rdar7265711_a(RDar7265711 *x) { 1174 id y = [x new_stuff]; // expected-warning{{leak}} 1175} 1176 1177void rdar7265711_b(RDar7265711 *x) { 1178 id y = [x new_stuff]; // no-warning 1179 [y release]; 1180} 1181 1182//===----------------------------------------------------------------------===// 1183// <rdar://problem/7306898> clang thinks [NSCursor dragCopyCursor] returns a 1184// retained reference 1185//===----------------------------------------------------------------------===// 1186 1187@interface NSCursor : NSObject 1188+ (NSCursor *)dragCopyCursor; 1189@end 1190 1191void rdar7306898(void) { 1192 // 'dragCopyCursor' does not follow Cocoa's fundamental rule. It is a noun, not an sentence 1193 // implying a 'copy' of something. 1194 NSCursor *c = [NSCursor dragCopyCursor]; // no-warning 1195 NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}} 1196} 1197 1198//===----------------------------------------------------------------------===// 1199// <rdar://problem/7252064> sending 'release', 'retain', etc. to a Class 1200// directly is not likely what the user intended 1201//===----------------------------------------------------------------------===// 1202 1203@interface RDar7252064 : NSObject @end 1204void rdar7252064(void) { 1205 [RDar7252064 release]; // expected-warning{{The 'release' message should be sent to instances of class 'RDar7252064' and not the class directly}} 1206 [RDar7252064 retain]; // expected-warning{{The 'retain' message should be sent to instances of class 'RDar7252064' and not the class directly}} 1207 [RDar7252064 autorelease]; // expected-warning{{The 'autorelease' message should be sent to instances of class 'RDar7252064' and not the class directly}} 1208 [NSAutoreleasePool drain]; // expected-warning{{method '+drain' not found}} expected-warning{{The 'drain' message should be sent to instances of class 'NSAutoreleasePool' and not the class directly}} 1209} 1210 1211//===----------------------------------------------------------------------===// 1212// Tests of ownership attributes. 1213//===----------------------------------------------------------------------===// 1214 1215typedef NSString* MyStringTy; 1216 1217@protocol FooP; 1218 1219@interface TestOwnershipAttr : NSObject 1220- (NSString*) returnsAnOwnedString NS_RETURNS_RETAINED; // no-warning 1221- (NSString*) returnsAnOwnedCFString CF_RETURNS_RETAINED; // no-warning 1222- (MyStringTy) returnsAnOwnedTypedString NS_RETURNS_RETAINED; // no-warning 1223- (NSString*) newString NS_RETURNS_NOT_RETAINED; // no-warning 1224- (NSString*) newStringNoAttr; 1225- (int) returnsAnOwnedInt NS_RETURNS_RETAINED; // expected-warning{{'ns_returns_retained' attribute only applies to methods that return an Objective-C object}} 1226- (id) pseudoInit NS_CONSUMES_SELF NS_RETURNS_RETAINED; 1227+ (void) consume:(id) NS_CONSUMED x; 1228+ (void) consume2:(id) CF_CONSUMED x; 1229@end 1230 1231static int ownership_attribute_doesnt_go_here NS_RETURNS_RETAINED; // expected-warning{{'ns_returns_retained' attribute only applies to functions and methods}} 1232 1233void test_attr_1(TestOwnershipAttr *X) { 1234 NSString *str = [X returnsAnOwnedString]; // expected-warning{{leak}} 1235} 1236 1237void test_attr_1b(TestOwnershipAttr *X) { 1238 NSString *str = [X returnsAnOwnedCFString]; // expected-warning{{leak}} 1239} 1240 1241void test_attr1c(TestOwnershipAttr *X) { 1242 NSString *str = [X newString]; // no-warning 1243 NSString *str2 = [X newStringNoAttr]; // expected-warning{{leak}} 1244} 1245 1246void testattr2_a() { 1247 TestOwnershipAttr *x = [TestOwnershipAttr alloc]; // expected-warning{{leak}} 1248} 1249 1250void testattr2_b() { 1251 TestOwnershipAttr *x = [[TestOwnershipAttr alloc] pseudoInit]; // expected-warning{{leak}} 1252} 1253 1254void testattr2_c() { 1255 TestOwnershipAttr *x = [[TestOwnershipAttr alloc] pseudoInit]; // no-warning 1256 [x release]; 1257} 1258 1259void testattr3() { 1260 TestOwnershipAttr *x = [TestOwnershipAttr alloc]; // no-warning 1261 [TestOwnershipAttr consume:x]; 1262 TestOwnershipAttr *y = [TestOwnershipAttr alloc]; // no-warning 1263 [TestOwnershipAttr consume2:y]; 1264} 1265 1266void consume_ns(id NS_CONSUMED x); 1267void consume_cf(id CF_CONSUMED x); 1268 1269void testattr4() { 1270 TestOwnershipAttr *x = [TestOwnershipAttr alloc]; // no-warning 1271 consume_ns(x); 1272 TestOwnershipAttr *y = [TestOwnershipAttr alloc]; // no-warning 1273 consume_cf(y); 1274} 1275 1276 1277@interface MyClassTestCFAttr : NSObject {} 1278- (NSDate*) returnsCFRetained CF_RETURNS_RETAINED; 1279- (CFDateRef) returnsCFRetainedAsCF CF_RETURNS_RETAINED; 1280- (CFDateRef) newCFRetainedAsCF CF_RETURNS_NOT_RETAINED; 1281- (CFDateRef) newCFRetainedAsCFNoAttr; 1282- (NSDate*) alsoReturnsRetained; 1283- (CFDateRef) alsoReturnsRetainedAsCF; 1284- (NSDate*) returnsNSRetained NS_RETURNS_RETAINED; 1285@end 1286 1287CF_RETURNS_RETAINED 1288CFDateRef returnsRetainedCFDate() { 1289 return CFDateCreate(0, CFAbsoluteTimeGetCurrent()); 1290} 1291 1292@implementation MyClassTestCFAttr 1293- (NSDate*) returnsCFRetained { 1294 return (NSDate*) returnsRetainedCFDate(); // No leak. 1295} 1296 1297- (CFDateRef) returnsCFRetainedAsCF { 1298 return returnsRetainedCFDate(); // No leak. 1299} 1300 1301- (CFDateRef) newCFRetainedAsCF { 1302 return (CFDateRef)[(id)[self returnsCFRetainedAsCF] autorelease]; 1303} 1304 1305- (CFDateRef) newCFRetainedAsCFNoAttr { 1306 return (CFDateRef)[(id)[self returnsCFRetainedAsCF] autorelease]; // expected-warning{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} 1307} 1308 1309- (NSDate*) alsoReturnsRetained { 1310 return (NSDate*) returnsRetainedCFDate(); // expected-warning{{leak}} 1311} 1312 1313- (CFDateRef) alsoReturnsRetainedAsCF { 1314 return returnsRetainedCFDate(); // expected-warning{{leak}} 1315} 1316 1317 1318- (NSDate*) returnsNSRetained { 1319 return (NSDate*) returnsRetainedCFDate(); // no-warning 1320} 1321@end 1322 1323//===----------------------------------------------------------------------===// 1324// Test that leaks post-dominated by "panic" functions are not reported. 1325// 1326// <rdar://problem/5905851> do not report a leak when post-dominated by a call 1327// to a noreturn or panic function 1328//===----------------------------------------------------------------------===// 1329 1330void panic() __attribute__((noreturn)); 1331void panic_not_in_hardcoded_list() __attribute__((noreturn)); 1332 1333void test_panic_negative() { 1334 signed z = 1; 1335 CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // expected-warning{{leak}} 1336} 1337 1338void test_panic_positive() { 1339 signed z = 1; 1340 CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // no-warning 1341 panic(); 1342} 1343 1344void test_panic_neg_2(int x) { 1345 signed z = 1; 1346 CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // expected-warning{{leak}} 1347 if (x) 1348 panic(); 1349} 1350 1351void test_panic_pos_2(int x) { 1352 signed z = 1; 1353 CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // no-warning 1354 if (x) 1355 panic(); 1356 if (!x) { 1357 // This showed up in <rdar://problem/7796563>, where we silently missed checking 1358 // the function type for noreturn. "panic()" is a hard-coded known panic function 1359 // that isn't always noreturn. 1360 panic_not_in_hardcoded_list(); 1361 } 1362} 1363 1364//===----------------------------------------------------------------------===// 1365// Test uses of blocks (closures) 1366//===----------------------------------------------------------------------===// 1367 1368void test_blocks_1_pos(void) { 1369 NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}} 1370 ^{}(); 1371} 1372 1373void test_blocks_1_indirect_release(void) { 1374 NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning 1375 ^{ [number release]; }(); 1376} 1377 1378void test_blocks_1_indirect_retain(void) { 1379 // Eventually this should be reported as a leak. 1380 NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning 1381 ^{ [number retain]; }(); 1382} 1383 1384void test_blocks_1_indirect_release_via_call(void) { 1385 NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning 1386 ^(NSObject *o){ [o release]; }(number); 1387} 1388 1389void test_blocks_1_indirect_retain_via_call(void) { 1390 // Eventually this should be reported as a leak. 1391 NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning 1392 ^(NSObject *o){ [o retain]; }(number); 1393} 1394 1395//===--------------------------------------------------------------------===// 1396// Test sending message to super that returns an object alias. Previously 1397// this caused a crash in the analyzer. 1398//===--------------------------------------------------------------------===// 1399 1400@interface Rdar8015556 : NSObject {} @end 1401@implementation Rdar8015556 1402- (id)retain { 1403 return [super retain]; 1404} 1405@end 1406 1407// <rdar://problem/8272168> - Correcly handle Class<...> in Cocoa Conventions 1408// detector. 1409 1410@protocol Prot_R8272168 @end 1411Class <Prot_R8272168> GetAClassThatImplementsProt_R8272168(); 1412void r8272168() { 1413 GetAClassThatImplementsProt_R8272168(); 1414} 1415 1416// Test case for <rdar://problem/8356342>, which in the past triggered 1417// a false positive. 1418@interface RDar8356342 1419- (NSDate*) rdar8356342:(NSDate *)inValue; 1420@end 1421 1422@implementation RDar8356342 1423- (NSDate*) rdar8356342:(NSDate*)inValue { 1424 NSDate *outValue = inValue; 1425 if (outValue == 0) 1426 outValue = [[NSDate alloc] init]; // no-warning 1427 1428 if (outValue != inValue) 1429 [outValue autorelease]; 1430 1431 return outValue; 1432} 1433@end 1434 1435// <rdar://problem/8724287> - This test case previously crashed because 1436// of a bug in BugReporter. 1437extern const void *CFDictionaryGetValue(CFDictionaryRef theDict, const void *key); 1438typedef struct __CFError * CFErrorRef; 1439extern const CFStringRef kCFErrorUnderlyingErrorKey; 1440extern CFDictionaryRef CFErrorCopyUserInfo(CFErrorRef err); 1441static void rdar_8724287(CFErrorRef error) 1442{ 1443 CFErrorRef error_to_dump; 1444 1445 error_to_dump = error; 1446 while (error_to_dump != ((void*)0)) { 1447 CFDictionaryRef info; 1448 1449 info = CFErrorCopyUserInfo(error_to_dump); // expected-warning{{Potential leak of an object allocated on line 1449 and stored into 'info'}} 1450 1451 if (info != ((void*)0)) { 1452 } 1453 1454 error_to_dump = (CFErrorRef) CFDictionaryGetValue(info, kCFErrorUnderlyingErrorKey); 1455 } 1456} 1457 1458// <rdar://problem/9234108> - Make sure the model applies cf_consumed 1459// correctly in argument positions besides the first. 1460extern void *CFStringCreate(void); 1461extern void rdar_9234108_helper(void *key, void * CF_CONSUMED value); 1462void rdar_9234108() { 1463 rdar_9234108_helper(0, CFStringCreate()); 1464} 1465 1466// <rdar://problem/9726279> - Make sure that objc_method_family works 1467// to override naming conventions. 1468struct TwoDoubles { 1469 double one; 1470 double two; 1471}; 1472typedef struct TwoDoubles TwoDoubles; 1473 1474@interface NSValue (Mine) 1475- (id)_prefix_initWithTwoDoubles:(TwoDoubles)twoDoubles __attribute__((objc_method_family(init))); 1476@end 1477 1478@implementation NSValue (Mine) 1479- (id)_prefix_initWithTwoDoubles:(TwoDoubles)twoDoubles 1480{ 1481 return [self init]; 1482} 1483@end 1484 1485void rdar9726279() { 1486 TwoDoubles twoDoubles = { 0.0, 0.0 }; 1487 NSValue *value = [[NSValue alloc] _prefix_initWithTwoDoubles:twoDoubles]; 1488 [value release]; 1489} 1490 1491// <rdar://problem/9732321> 1492// Test camelcase support for CF conventions. While Core Foundation APIs 1493// don't use camel casing, other code is allowed to use it. 1494CFArrayRef camelcase_create_1() { 1495 return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning 1496} 1497 1498CFArrayRef camelcase_createno() { 1499 return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning {{leak}} 1500} 1501 1502CFArrayRef camelcase_copy() { 1503 return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning 1504} 1505 1506CFArrayRef camelcase_copying() { 1507 return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning {{leak}} 1508} 1509 1510CFArrayRef copyCamelCase() { 1511 return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning 1512} 1513 1514CFArrayRef __copyCamelCase() { 1515 return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning 1516} 1517 1518CFArrayRef __createCamelCase() { 1519 return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning 1520} 1521 1522CFArrayRef camel_create() { 1523 return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning 1524} 1525 1526 1527CFArrayRef camel_creat() { 1528 return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning {{leak}} 1529} 1530 1531CFArrayRef camel_copy() { 1532 return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning 1533} 1534 1535CFArrayRef camel_copyMachine() { 1536 return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning 1537} 1538 1539CFArrayRef camel_copymachine() { 1540 return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning {{leak}} 1541} 1542 1543