1// RUN: rm -f %t.objc.plist %t.objcpp.plist 2// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10\ 3// RUN: -analyzer-checker=core,osx.coreFoundation.CFRetainRelease\ 4// RUN: -analyzer-checker=osx.cocoa.ClassRelease,osx.cocoa.RetainCount\ 5// RUN: -analyzer-checker=debug.ExprInspection -fblocks -verify %s\ 6// RUN: -Wno-objc-root-class -analyzer-output=plist -o %t.objc.plist 7// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10\ 8// RUN: -analyzer-checker=core,osx.coreFoundation.CFRetainRelease\ 9// RUN: -analyzer-checker=osx.cocoa.ClassRelease,osx.cocoa.RetainCount\ 10// RUN: -analyzer-checker=debug.ExprInspection -fblocks -verify %s\ 11// RUN: -Wno-objc-root-class -analyzer-output=plist -o %t.objcpp.plist\ 12// RUN: -x objective-c++ -std=gnu++98 13// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10\ 14// RUN: -analyzer-checker=core,osx.coreFoundation.CFRetainRelease\ 15// RUN: -analyzer-checker=osx.cocoa.ClassRelease,osx.cocoa.RetainCount\ 16// RUN: -analyzer-checker=debug.ExprInspection -fblocks -verify %s\ 17// RUN: -Wno-objc-root-class -x objective-c++ -std=gnu++98\ 18// RUN: -analyzer-config osx.cocoa.RetainCount:TrackNSCFStartParam=true\ 19// RUN: -DTRACK_START_PARAM 20// RUN: %normalize_plist <%t.objcpp.plist | diff -ub %S/Inputs/expected-plists/retain-release.m.objcpp.plist - 21// RUN: %normalize_plist <%t.objc.plist | diff -ub %S/Inputs/expected-plists/retain-release.m.objc.plist - 22 23void clang_analyzer_eval(int); 24 25#if __has_feature(attribute_ns_returns_retained) 26#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained)) 27#endif 28#if __has_feature(attribute_cf_returns_retained) 29#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained)) 30#endif 31#if __has_feature(attribute_ns_returns_not_retained) 32#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained)) 33#endif 34#if __has_feature(attribute_cf_returns_not_retained) 35#define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained)) 36#endif 37#if __has_feature(attribute_ns_consumes_self) 38#define NS_CONSUMES_SELF __attribute__((ns_consumes_self)) 39#endif 40#if __has_feature(attribute_ns_consumed) 41#define NS_CONSUMED __attribute__((ns_consumed)) 42#endif 43#if __has_feature(attribute_cf_consumed) 44#define CF_CONSUMED __attribute__((cf_consumed)) 45#endif 46#if __has_attribute(ns_returns_autoreleased) 47#define NS_RETURNS_AUTORELEASED __attribute__((ns_returns_autoreleased)) 48#endif 49 50//===----------------------------------------------------------------------===// 51// The following code is reduced using delta-debugging from Mac OS X headers: 52// 53// #include <Cocoa/Cocoa.h> 54// #include <CoreFoundation/CoreFoundation.h> 55// #include <DiskArbitration/DiskArbitration.h> 56// #include <QuartzCore/QuartzCore.h> 57// #include <Quartz/Quartz.h> 58// #include <IOKit/IOKitLib.h> 59// 60// It includes the basic definitions for the test cases below. 61//===----------------------------------------------------------------------===// 62 63typedef unsigned int __darwin_natural_t; 64typedef unsigned long uintptr_t; 65typedef unsigned int uint32_t; 66typedef unsigned long long uint64_t; 67typedef unsigned int UInt32; 68typedef signed long CFIndex; 69typedef CFIndex CFByteOrder; 70typedef struct { 71 CFIndex location; 72 CFIndex length; 73} CFRange; 74static __inline__ __attribute__((always_inline)) CFRange CFRangeMake(CFIndex loc, CFIndex len) { 75 CFRange range; 76 range.location = loc; 77 range.length = len; 78 return range; 79} 80typedef const void * CFTypeRef; 81typedef const struct __CFString * CFStringRef; 82typedef const struct __CFAllocator * CFAllocatorRef; 83extern const CFAllocatorRef kCFAllocatorDefault; 84 85extern CFTypeRef CFRetain(CFTypeRef cf); 86extern void CFRelease(CFTypeRef cf); 87extern CFTypeRef CFMakeCollectable(CFTypeRef cf); 88extern CFTypeRef CFAutorelease(CFTypeRef CF_CONSUMED cf); 89 90typedef struct { 91} 92CFArrayCallBacks; 93extern const CFArrayCallBacks kCFTypeArrayCallBacks; 94typedef const struct __CFArray * CFArrayRef; 95typedef struct __CFArray * CFMutableArrayRef; 96extern CFMutableArrayRef CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFArrayCallBacks *callBacks); 97extern const void *CFArrayGetValueAtIndex(CFArrayRef theArray, CFIndex idx); 98extern void CFArrayAppendValue(CFMutableArrayRef theArray, const void *value); 99typedef struct { 100} 101CFDictionaryKeyCallBacks; 102extern const CFDictionaryKeyCallBacks kCFTypeDictionaryKeyCallBacks; 103typedef struct { 104} 105CFDictionaryValueCallBacks; 106extern const CFDictionaryValueCallBacks kCFTypeDictionaryValueCallBacks; 107typedef const struct __CFDictionary * CFDictionaryRef; 108typedef struct __CFDictionary * CFMutableDictionaryRef; 109extern CFMutableDictionaryRef CFDictionaryCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFDictionaryKeyCallBacks *keyCallBacks, const CFDictionaryValueCallBacks *valueCallBacks); 110typedef UInt32 CFStringEncoding; 111enum { 112kCFStringEncodingMacRoman = 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 }; 113extern CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding); 114typedef double CFTimeInterval; 115typedef CFTimeInterval CFAbsoluteTime; 116extern CFAbsoluteTime CFAbsoluteTimeGetCurrent(void); 117typedef const struct __CFDate * CFDateRef; 118extern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at); 119extern CFAbsoluteTime CFDateGetAbsoluteTime(CFDateRef theDate); 120typedef __darwin_natural_t natural_t; 121typedef natural_t mach_port_name_t; 122typedef mach_port_name_t mach_port_t; 123typedef int kern_return_t; 124typedef kern_return_t mach_error_t; 125enum { 126kCFNumberSInt8Type = 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 }; 127typedef CFIndex CFNumberType; 128typedef const struct __CFNumber * CFNumberRef; 129extern CFNumberRef CFNumberCreate(CFAllocatorRef allocator, CFNumberType theType, const void *valuePtr); 130typedef const struct __CFAttributedString *CFAttributedStringRef; 131typedef struct __CFAttributedString *CFMutableAttributedStringRef; 132extern CFAttributedStringRef CFAttributedStringCreate(CFAllocatorRef alloc, CFStringRef str, CFDictionaryRef attributes) ; 133extern CFMutableAttributedStringRef CFAttributedStringCreateMutableCopy(CFAllocatorRef alloc, CFIndex maxLength, CFAttributedStringRef aStr) ; 134extern void CFAttributedStringSetAttribute(CFMutableAttributedStringRef aStr, CFRange range, CFStringRef attrName, CFTypeRef value) ; 135typedef signed char BOOL; 136typedef unsigned long NSUInteger; 137@class NSString, Protocol; 138extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2))); 139typedef struct _NSZone NSZone; 140@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; 141@protocol NSObject 142- (BOOL)isEqual:(id)object; 143- (id)retain; 144- (oneway void)release; 145- (id)autorelease; 146- (NSString *)description; 147- (id)init; 148@end 149@protocol NSCopying 150- (id)copyWithZone:(NSZone *)zone; 151@end 152@protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; 153@end 154@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; 155@end 156@interface NSObject <NSObject> {} 157+ (id)allocWithZone:(NSZone *)zone; 158+ (id)alloc; 159+ (id)new; 160- (void)dealloc; 161@end 162@interface NSObject (NSCoderMethods) 163- (id)awakeAfterUsingCoder:(NSCoder *)aDecoder; 164@end 165extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone); 166typedef struct { 167} 168NSFastEnumerationState; 169@protocol NSFastEnumeration 170- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len; 171@end 172@class NSString, NSDictionary; 173@interface NSValue : NSObject <NSCopying, NSCoding> - (void)getValue:(void *)value; 174@end 175@interface NSNumber : NSValue 176- (char)charValue; 177- (id)initWithInt:(int)value; 178+ (NSNumber *)numberWithInt:(int)value; 179@end 180@class NSString; 181@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration> 182- (NSUInteger)count; 183- (id)initWithObjects:(const id [])objects count:(NSUInteger)cnt; 184+ (id)arrayWithObject:(id)anObject; 185+ (id)arrayWithObjects:(const id [])objects count:(NSUInteger)cnt; 186+ (id)arrayWithObjects:(id)firstObj, ... __attribute__((sentinel(0,1))); 187- (id)initWithObjects:(id)firstObj, ... __attribute__((sentinel(0,1))); 188- (id)initWithArray:(NSArray *)array; 189@end @interface NSArray (NSArrayCreation) + (id)array; 190@end @interface NSAutoreleasePool : NSObject { 191} 192- (void)drain; 193@end extern NSString * const NSBundleDidLoadNotification; 194typedef double NSTimeInterval; 195@interface NSDate : NSObject <NSCopying, NSCoding> - (NSTimeInterval)timeIntervalSinceReferenceDate; 196@end typedef unsigned short unichar; 197@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding> 198- (NSUInteger)length; 199- (NSString *)stringByAppendingString:(NSString *)aString; 200- ( const char *)UTF8String; 201- (id)initWithUTF8String:(const char *)nullTerminatedCString; 202+ (id)stringWithUTF8String:(const char *)nullTerminatedCString; 203@end @class NSString, NSURL, NSError; 204@interface NSData : NSObject <NSCopying, NSMutableCopying, NSCoding> - (NSUInteger)length; 205+ (id)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length; 206+ (id)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length freeWhenDone:(BOOL)b; 207@end @class NSLocale, NSDate, NSCalendar, NSTimeZone, NSError, NSArray, NSMutableDictionary; 208@interface NSDictionary : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration> 209- (NSUInteger)count; 210+ (id)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; 211+ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id <NSCopying> [])keys count:(NSUInteger)cnt; 212@end 213@interface NSMutableDictionary : NSDictionary - (void)removeObjectForKey:(id)aKey; 214- (void)setObject:(id)anObject forKey:(id)aKey; 215@end 216@interface NSMutableDictionary (NSMutableDictionaryCreation) + (id)dictionaryWithCapacity:(NSUInteger)numItems; 217@end 218 219@interface NSNull : NSObject 220+ (NSNull*) null; 221@end 222 223typedef double CGFloat; 224struct CGSize { 225}; 226typedef struct CGSize CGSize; 227struct CGRect { 228}; 229typedef struct CGRect CGRect; 230typedef mach_port_t io_object_t; 231typedef char io_name_t[128]; 232typedef io_object_t io_iterator_t; 233typedef io_object_t io_service_t; 234typedef struct IONotificationPort * IONotificationPortRef; 235typedef void (*IOServiceMatchingCallback)( void * refcon, io_iterator_t iterator ); 236io_service_t IOServiceGetMatchingService( mach_port_t mainPort, CFDictionaryRef matching ); 237kern_return_t IOServiceGetMatchingServices( mach_port_t mainPort, CFDictionaryRef matching, io_iterator_t * existing ); 238kern_return_t IOServiceAddNotification( mach_port_t mainPort, const io_name_t notificationType, CFDictionaryRef matching, mach_port_t wakePort, uintptr_t reference, io_iterator_t * notification ) __attribute__((deprecated)); // expected-note {{'IOServiceAddNotification' has been explicitly marked deprecated here}} 239kern_return_t IOServiceAddMatchingNotification( IONotificationPortRef notifyPort, const io_name_t notificationType, CFDictionaryRef matching, IOServiceMatchingCallback callback, void * refCon, io_iterator_t * notification ); 240CFMutableDictionaryRef IOServiceMatching( const char * name ); 241CFMutableDictionaryRef IOServiceNameMatching( const char * name ); 242CFMutableDictionaryRef IOBSDNameMatching( mach_port_t mainPort, uint32_t options, const char * bsdName ); 243CFMutableDictionaryRef IOOpenFirmwarePathMatching( mach_port_t mainPort, uint32_t options, const char * path ); 244CFMutableDictionaryRef IORegistryEntryIDMatching( uint64_t entryID ); 245typedef struct __DASession * DASessionRef; 246extern DASessionRef DASessionCreate( CFAllocatorRef allocator ); 247typedef struct __DADisk * DADiskRef; 248extern DADiskRef DADiskCreateFromBSDName( CFAllocatorRef allocator, DASessionRef session, const char * name ); 249extern DADiskRef DADiskCreateFromIOMedia( CFAllocatorRef allocator, DASessionRef session, io_service_t media ); 250extern CFDictionaryRef DADiskCopyDescription( DADiskRef disk ); 251extern DADiskRef DADiskCopyWholeDisk( DADiskRef disk ); 252@interface NSTask : NSObject - (id)init; 253@end typedef struct CGColorSpace *CGColorSpaceRef; 254typedef struct CGImage *CGImageRef; 255typedef struct CGLayer *CGLayerRef; 256@interface NSResponder : NSObject <NSCoding> { 257} 258@end @protocol NSAnimatablePropertyContainer - (id)animator; 259@end extern NSString *NSAnimationTriggerOrderIn ; 260@interface NSView : NSResponder <NSAnimatablePropertyContainer> { 261} 262@end @protocol NSValidatedUserInterfaceItem - (SEL)action; 263@end @protocol NSUserInterfaceValidations - (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)anItem; 264@end @class NSDate, NSDictionary, NSError, NSException, NSNotification; 265@class NSTextField, NSPanel, NSArray, NSWindow, NSImage, NSButton, NSError; 266@interface NSApplication : NSResponder <NSUserInterfaceValidations> { 267} 268- (void)beginSheet:(NSWindow *)sheet modalForWindow:(NSWindow *)docWindow modalDelegate:(id)modalDelegate didEndSelector:(SEL)didEndSelector contextInfo:(void *)contextInfo; 269@end enum { 270NSTerminateCancel = 0, NSTerminateNow = 1, NSTerminateLater = 2 }; 271typedef NSUInteger NSApplicationTerminateReply; 272@protocol NSApplicationDelegate <NSObject> @optional - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender; 273@end @class NSAttributedString, NSEvent, NSFont, NSFormatter, NSImage, NSMenu, NSText, NSView, NSTextView; 274@interface NSCell : NSObject <NSCopying, NSCoding> { 275} 276@end 277typedef struct { 278} 279CVTimeStamp; 280@interface CIImage : NSObject <NSCoding, NSCopying> { 281} 282typedef int CIFormat; 283@end enum { 284kDAReturnSuccess = 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 }; 285typedef mach_error_t DAReturn; 286typedef const struct __DADissenter * DADissenterRef; 287extern DADissenterRef DADissenterCreate( CFAllocatorRef allocator, DAReturn status, CFStringRef string ); 288@interface CIContext: NSObject { 289} 290- (CGImageRef)createCGImage:(CIImage *)im fromRect:(CGRect)r; 291- (CGImageRef)createCGImage:(CIImage *)im fromRect:(CGRect)r format:(CIFormat)f colorSpace:(CGColorSpaceRef)cs; 292- (CGLayerRef)createCGLayerWithSize:(CGSize)size info:(CFDictionaryRef)d; 293@end extern NSString* const QCRendererEventKey; 294@protocol QCCompositionRenderer - (NSDictionary*) attributes; 295@end @interface QCRenderer : NSObject <QCCompositionRenderer> { 296} 297- (id) createSnapshotImageOfType:(NSString*)type; 298@end extern NSString* const QCViewDidStartRenderingNotification; 299@interface QCView : NSView <QCCompositionRenderer> { 300} 301- (id) createSnapshotImageOfType:(NSString*)type; 302@end enum { 303ICEXIFOrientation1 = 1, ICEXIFOrientation2 = 2, ICEXIFOrientation3 = 3, ICEXIFOrientation4 = 4, ICEXIFOrientation5 = 5, ICEXIFOrientation6 = 6, ICEXIFOrientation7 = 7, ICEXIFOrientation8 = 8, }; 304@class ICDevice; 305@protocol ICDeviceDelegate <NSObject> @required - (void)didRemoveDevice:(ICDevice*)device; 306@end extern NSString *const ICScannerStatusWarmingUp; 307@class ICScannerDevice; 308@protocol ICScannerDeviceDelegate <ICDeviceDelegate> @optional - (void)scannerDeviceDidBecomeAvailable:(ICScannerDevice*)scanner; 309@end 310 311typedef long unsigned int __darwin_size_t; 312typedef __darwin_size_t size_t; 313typedef unsigned long CFTypeID; 314struct CGPoint { 315 CGFloat x; 316 CGFloat y; 317}; 318typedef struct CGPoint CGPoint; 319typedef struct CGGradient *CGGradientRef; 320typedef uint32_t CGGradientDrawingOptions; 321extern CFTypeID CGGradientGetTypeID(void); 322extern CGGradientRef CGGradientCreateWithColorComponents(CGColorSpaceRef 323 space, const CGFloat components[], const CGFloat locations[], size_t count); 324extern CGGradientRef CGGradientCreateWithColors(CGColorSpaceRef space, 325 CFArrayRef colors, const CGFloat locations[]); 326extern CGGradientRef CGGradientRetain(CGGradientRef gradient); 327extern void CGGradientRelease(CGGradientRef gradient); 328typedef struct CGContext *CGContextRef; 329extern void CGContextDrawLinearGradient(CGContextRef context, 330 CGGradientRef gradient, CGPoint startPoint, CGPoint endPoint, 331 CGGradientDrawingOptions options); 332extern CGColorSpaceRef CGColorSpaceCreateDeviceRGB(void); 333 334@interface NSMutableArray : NSObject 335- (void)addObject:(id)object; 336+ (id)array; 337@end 338 339// This is how NSMakeCollectable is declared in the OS X 10.8 headers. 340id NSMakeCollectable(CFTypeRef __attribute__((cf_consumed))) __attribute__((ns_returns_retained)); 341 342typedef const struct __CFUUID * CFUUIDRef; 343 344extern 345void *CFPlugInInstanceCreate(CFAllocatorRef allocator, CFUUIDRef factoryUUID, CFUUIDRef typeUUID); 346typedef struct { 347 int ref; 348} isl_basic_map; 349 350//===----------------------------------------------------------------------===// 351// Test cases. 352//===----------------------------------------------------------------------===// 353 354CFAbsoluteTime f1(void) { 355 CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); 356 CFDateRef date = CFDateCreate(0, t); 357 CFRetain(date); 358 CFRelease(date); 359 CFDateGetAbsoluteTime(date); // no-warning 360 CFRelease(date); 361 t = CFDateGetAbsoluteTime(date); // expected-warning{{Reference-counted object is used after it is released}} 362 return t; 363} 364 365CFAbsoluteTime f2(void) { 366 CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); 367 CFDateRef date = CFDateCreate(0, t); 368 [((NSDate*) date) retain]; 369 CFRelease(date); 370 CFDateGetAbsoluteTime(date); // no-warning 371 [((NSDate*) date) release]; 372 t = CFDateGetAbsoluteTime(date); // expected-warning{{Reference-counted object is used after it is released}} 373 return t; 374} 375 376 377NSDate* global_x; 378 379// Test to see if we suppress an error when we store the pointer 380// to a global. 381 382CFAbsoluteTime f3(void) { 383 CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); 384 CFDateRef date = CFDateCreate(0, t); 385 [((NSDate*) date) retain]; 386 CFRelease(date); 387 CFDateGetAbsoluteTime(date); // no-warning 388 global_x = (NSDate*) date; 389 [((NSDate*) date) release]; 390 t = CFDateGetAbsoluteTime(date); // no-warning 391 return t; 392} 393 394//--------------------------------------------------------------------------- 395// Test case 'f4' differs for region store and basic store. See 396// retain-release-region-store.m and retain-release-basic-store.m. 397//--------------------------------------------------------------------------- 398 399// Test a leak. 400 401CFAbsoluteTime f5(int x) { 402 CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); 403 CFDateRef date = CFDateCreate(0, t); // expected-warning{{leak}} 404 405 if (x) 406 CFRelease(date); 407 408 return t; 409} 410 411// Test a leak involving the return. 412 413CFDateRef f6(int x) { 414 CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); // expected-warning{{leak}} 415 CFRetain(date); 416 return date; 417} 418 419// Test a leak involving an overwrite. 420 421CFDateRef f7(void) { 422 CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); //expected-warning{{leak}} 423 CFRetain(date); 424 date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); // expected-warning {{leak}} 425 return date; 426} 427 428// Generalization of Create rule. MyDateCreate returns a CFXXXTypeRef, and 429// has the word create. 430CFDateRef MyDateCreate(void); 431 432CFDateRef f8(void) { 433 CFDateRef date = MyDateCreate(); // expected-warning{{leak}} 434 CFRetain(date); 435 return date; 436} 437 438__attribute__((cf_returns_retained)) CFDateRef f9(void) { 439 CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); // no-warning 440 int *p = 0; 441 // When allocations fail, CFDateCreate can return null. 442 if (!date) *p = 1; // expected-warning{{null}} 443 return date; 444} 445 446// Handle DiskArbitration API: 447// 448// http://developer.apple.com/DOCUMENTATION/DARWIN/Reference/DiscArbitrationFramework/ 449// 450void f10(io_service_t media, DADiskRef d, CFStringRef s) { 451 DADiskRef disk = DADiskCreateFromBSDName(kCFAllocatorDefault, 0, "hello"); // expected-warning{{leak}} 452 if (disk) NSLog(@"ok"); 453 454 disk = DADiskCreateFromIOMedia(kCFAllocatorDefault, 0, media); // expected-warning{{leak}} 455 if (disk) NSLog(@"ok"); 456 457 CFDictionaryRef dict = DADiskCopyDescription(d); // expected-warning{{leak}} 458 if (dict) NSLog(@"ok"); 459 460 disk = DADiskCopyWholeDisk(d); // expected-warning{{leak}} 461 if (disk) NSLog(@"ok"); 462 463 DADissenterRef dissenter = DADissenterCreate(kCFAllocatorDefault, // expected-warning{{leak}} 464 kDAReturnSuccess, s); 465 if (dissenter) NSLog(@"ok"); 466 467 DASessionRef session = DASessionCreate(kCFAllocatorDefault); // expected-warning{{leak}} 468 if (session) NSLog(@"ok"); 469} 470 471 472// Handle CoreMedia API 473 474struct CMFoo; 475typedef struct CMFoo *CMFooRef; 476 477CMFooRef CMCreateFooRef(void); 478CMFooRef CMGetFooRef(void); 479 480typedef signed long SInt32; 481typedef SInt32 OSStatus; 482OSStatus CMCreateFooAndReturnViaOutParameter(CMFooRef * CF_RETURNS_RETAINED fooOut); 483 484void testLeakCoreMediaReferenceType(void) { 485 CMFooRef f = CMCreateFooRef(); // expected-warning{{leak}} 486} 487 488void testOverReleaseMediaReferenceType(void) { 489 CMFooRef f = CMGetFooRef(); 490 CFRelease(f); // expected-warning{{Incorrect decrement of the reference count}} 491} 492 493void testOkToReleaseReturnsRetainedOutParameter(void) { 494 CMFooRef foo = 0; 495 OSStatus status = CMCreateFooAndReturnViaOutParameter(&foo); 496 497 if (status != 0) 498 return; 499 500 CFRelease(foo); // no-warning 501} 502 503void testLeakWithReturnsRetainedOutParameter(void) { 504 CMFooRef foo = 0; 505 OSStatus status = CMCreateFooAndReturnViaOutParameter(&foo); 506 507 if (status != 0) 508 return; 509 510 // FIXME: Ideally we would report a leak here since it is the caller's 511 // responsibility to release 'foo'. However, we don't currently have 512 // a mechanism in this checker to only require a release when a successful 513 // status is returned. 514} 515 516typedef CFTypeRef CMBufferRef; 517 518typedef CFTypeRef *CMBufferQueueRef; 519 520CMBufferRef CMBufferQueueDequeueAndRetain(CMBufferQueueRef); 521 522void testCMBufferQueueDequeueAndRetain(CMBufferQueueRef queue) { 523 CMBufferRef buffer = CMBufferQueueDequeueAndRetain(queue); // expected-warning{{Potential leak of an object stored into 'buffer'}} 524 // There's a state split due to the eagerly-assume behavior. 525 // The point here is that we don't treat CMBufferQueueDequeueAndRetain 526 // as some sort of CFRetain() that returns its argument. 527 clang_analyzer_eval((CMFooRef)buffer == (CMFooRef)queue); // expected-warning{{TRUE}} 528 // expected-warning@-1{{FALSE}} 529} 530 531// Test retain/release checker with CFString and CFMutableArray. 532void f11(void) { 533 // Create the array. 534 CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); 535 536 // Create a string. 537 CFStringRef s1 = CFStringCreateWithCString(0, "hello world", 538 kCFStringEncodingUTF8); 539 540 // Add the string to the array. 541 CFArrayAppendValue(A, s1); 542 543 // Decrement the reference count. 544 CFRelease(s1); // no-warning 545 546 // Get the string. We don't own it. 547 s1 = (CFStringRef) CFArrayGetValueAtIndex(A, 0); 548 549 // Release the array. 550 CFRelease(A); // no-warning 551 552 // Release the string. This is a bug. 553 CFRelease(s1); // expected-warning{{Incorrect decrement of the reference count}} 554} 555 556// PR 3337: Handle functions declared using typedefs. 557typedef CFTypeRef CREATEFUN(void); 558CREATEFUN MyCreateFun; 559 560void f12(void) { 561 CFTypeRef o = MyCreateFun(); // expected-warning {{leak}} 562} 563 564void f13_autorelease(void) { 565 CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning 566 [(id) A autorelease]; // no-warning 567} 568 569void f13_autorelease_b(void) { 570 CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); 571 [(id) A autorelease]; 572 [(id) A autorelease]; 573} // expected-warning{{Object autoreleased too many times}} 574 575CFMutableArrayRef f13_autorelease_c(void) { 576 CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); 577 [(id) A autorelease]; 578 [(id) A autorelease]; 579 return A; // expected-warning{{Object autoreleased too many times}} 580} 581 582CFMutableArrayRef f13_autorelease_d(void) { 583 CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); 584 [(id) A autorelease]; 585 [(id) A autorelease]; 586 CFMutableArrayRef B = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{Object autoreleased too many times}} 587 CFRelease(B); // no-warning 588 while (1) {} 589} 590 591 592// This case exercises the logic where the leak site is the same as the allocation site. 593void f14_leakimmediately(void) { 594 CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{leak}} 595} 596 597// Test that we track an allocated object beyond the point where the *name* 598// of the variable storing the reference is no longer live. 599void f15(void) { 600 // Create the array. 601 CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); 602 CFMutableArrayRef *B = &A; 603 // At this point, the name 'A' is no longer live. 604 CFRelease(*B); // no-warning 605} 606 607// Test when we pass NULL to CFRetain/CFRelease/CFMakeCollectable/CFAutorelease. 608void f16(int x, CFTypeRef p) { 609 if (p) 610 return; 611 612 switch (x) { 613 case 0: 614 CFRelease(p); // expected-warning{{Null pointer argument in call to CFRelease}} 615 break; 616 case 1: 617 CFRetain(p); // expected-warning{{Null pointer argument in call to CFRetain}} 618 break; 619 case 2: 620 CFMakeCollectable(p); // expected-warning{{Null pointer argument in call to CFMakeCollectable}} 621 break; 622 case 3: 623 CFAutorelease(p); // expected-warning{{Null pointer argument in call to CFAutorelease}} 624 break; 625 default: 626 break; 627 } 628} 629 630#ifdef TRACK_START_PARAM 631@interface TestParam : NSObject 632- (void) f:(id) object; 633@end 634 635@implementation TestParam 636- (void) f:(id) object { // expected-warning{{Potential leak of an object of type 'id'}} 637 [object retain]; 638 [object retain]; 639} 640@end 641#endif 642 643// Test that an object is non-null after CFRetain/CFRelease/CFMakeCollectable/CFAutorelease. 644void f17(int x, CFTypeRef p) { 645#ifdef TRACK_START_PARAM 646 // expected-warning@-2{{Potential leak of an object of type 'CFTypeRef'}} 647#endif 648 switch (x) { 649 case 0: 650 CFRelease(p); 651#ifdef TRACK_START_PARAM 652 // expected-warning@-2{{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} 653#endif 654 if (!p) 655 CFRelease(0); // no-warning 656 break; 657 case 1: 658 CFRetain(p); 659 if (!p) 660 CFRetain(0); // no-warning 661 break; 662 case 2: 663 CFMakeCollectable(p); 664 if (!p) 665 CFMakeCollectable(0); // no-warning 666 break; 667 case 3: 668 CFAutorelease(p); 669 if (!p) 670 CFAutorelease(0); // no-warning 671 break; 672 default: 673 break; 674 } 675} 676#ifdef TRACK_START_PARAM 677 // expected-warning@-2{{Object autoreleased too many times}} 678#endif 679 680__attribute__((annotate("rc_ownership_returns_retained"))) isl_basic_map *isl_basic_map_cow(__attribute__((annotate("rc_ownership_consumed"))) isl_basic_map *bmap); 681 682// Test custom diagnostics for generalized objects. 683void f18(__attribute__((annotate("rc_ownership_consumed"))) isl_basic_map *bmap) { 684 // After this call, 'bmap' has a +1 reference count. 685 bmap = isl_basic_map_cow(bmap); // expected-warning {{Potential leak of an object}} 686} 687 688// Test basic tracking of ivars associated with 'self'. For the retain/release 689// checker we currently do not want to flag leaks associated with stores 690// of tracked objects to ivars. 691@interface SelfIvarTest : NSObject { 692 id myObj; 693} 694- (void)test_self_tracking; 695@end 696 697@implementation SelfIvarTest 698- (void)test_self_tracking { 699 myObj = (id) CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning 700} 701@end 702 703// Test return of non-owned objects in contexts where an owned object 704// is expected. 705@interface TestReturnNotOwnedWhenExpectedOwned 706- (NSString*)newString; 707@end 708 709@implementation TestReturnNotOwnedWhenExpectedOwned 710- (NSString*)newString { 711 NSString *s = [NSString stringWithUTF8String:"hello"]; 712 return s; // expected-warning{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} 713} 714@end 715 716int isFoo(char c); 717 718static void rdar_6659160(char *inkind, char *inname) 719{ 720 // We currently expect that [NSObject alloc] cannot fail. This 721 // will be a toggled flag in the future. It can indeed return null, but 722 // Cocoa programmers generally aren't expected to reason about out-of-memory 723 // conditions. 724 NSString *kind = [[NSString alloc] initWithUTF8String:inkind]; // expected-warning{{leak}} 725 726 // We do allow stringWithUTF8String to fail. This isn't really correct, as 727 // far as returning 0. In most error conditions it will throw an exception. 728 // If allocation fails it could return 0, but again this 729 // isn't expected. 730 NSString *name = [NSString stringWithUTF8String:inname]; 731 if(!name) 732 return; 733 734 const char *kindC = 0; 735 const char *nameC = 0; 736 737 // In both cases, we cannot reach a point down below where we 738 // dereference kindC or nameC with either being null. This is because 739 // we assume that [NSObject alloc] doesn't fail and that we have the guard 740 // up above. 741 742 if(kind) 743 kindC = [kind UTF8String]; 744 if(name) 745 nameC = [name UTF8String]; 746 if(!isFoo(kindC[0])) // expected-warning{{null}} 747 return; 748 if(!isFoo(nameC[0])) // no-warning 749 return; 750 751 [kind release]; 752 [name release]; // expected-warning{{Incorrect decrement of the reference count}} 753} 754 755// PR 3677 - 'allocWithZone' should be treated as following the Cocoa naming 756// conventions with respect to 'return'ing ownership. 757@interface PR3677: NSObject @end 758@implementation PR3677 759+ (id)allocWithZone:(NSZone *)inZone { 760 return [super allocWithZone:inZone]; // no-warning 761} 762@end 763 764// PR 3820 - Reason about calls to -dealloc 765void pr3820_DeallocInsteadOfRelease(void) 766{ 767 id foo = [[NSString alloc] init]; // no-warning 768 [foo dealloc]; 769 // foo is not leaked, since it has been deallocated. 770} 771 772void pr3820_ReleaseAfterDealloc(void) 773{ 774 id foo = [[NSString alloc] init]; 775 [foo dealloc]; 776 [foo release]; // expected-warning{{used after it is release}} 777 // NSInternalInconsistencyException: message sent to deallocated object 778} 779 780void pr3820_DeallocAfterRelease(void) 781{ 782 NSLog(@"\n\n[%s]", __FUNCTION__); 783 id foo = [[NSString alloc] init]; 784 [foo release]; 785 [foo dealloc]; // expected-warning{{used after it is released}} 786 // message sent to released object 787} 788 789// The problem here is that 'length' binds to'($0 - 1)' after '--length', but 790// SimpleConstraintManager doesn't know how to reason about 791// '($0 - 1) > constant'. As a temporary hack, we drop the value of '($0 - 1)' 792// and conjure a new symbol. 793void rdar6704930(unsigned char *s, unsigned int length) { 794 NSString* name = 0; 795 if (s != 0) { 796 if (length > 0) { 797 while (length > 0) { 798 if (*s == ':') { 799 ++s; 800 --length; 801 name = [[NSString alloc] init]; // no-warning 802 break; 803 } 804 ++s; 805 --length; 806 } 807 if ((length == 0) && (name != 0)) { 808 [name release]; 809 name = 0; 810 } 811 if (length == 0) { // no ':' found -> use it all as name 812 name = [[NSString alloc] init]; // no-warning 813 } 814 } 815 } 816 817 if (name != 0) { 818 [name release]; 819 } 820} 821 822//===----------------------------------------------------------------------===// 823// One build of the analyzer accidentally stopped tracking the allocated 824// object after the 'retain'. 825//===----------------------------------------------------------------------===// 826 827@interface rdar_6833332 : NSObject <NSApplicationDelegate> { 828 NSWindow *window; 829} 830@property (nonatomic, retain) NSWindow *window; 831@end 832 833@implementation rdar_6833332 834@synthesize window; 835- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { 836 NSMutableDictionary *dict = [[NSMutableDictionary dictionaryWithCapacity:4] retain]; // expected-warning{{leak}} 837 838 [dict setObject:@"foo" forKey:@"bar"]; 839 840 NSLog(@"%@", dict); 841} 842- (void)dealloc { 843 [window release]; 844 [super dealloc]; 845} 846 847- (void)radar10102244 { 848 NSMutableDictionary *dict = [[NSMutableDictionary dictionaryWithCapacity:4] retain]; // expected-warning{{leak}} 849 if (window) 850 NSLog(@"%@", window); 851} 852@end 853 854//===----------------------------------------------------------------------===// 855// clang checker fails to catch use-after-release 856//===----------------------------------------------------------------------===// 857int rdar_6257780_Case1(void) { 858 NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 859 NSArray *array = [NSArray array]; 860 [array release]; // expected-warning{{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} 861 [pool drain]; 862 return 0; 863} 864 865//===----------------------------------------------------------------------===// 866// Analyzer is confused about NSAutoreleasePool -allocWithZone:. 867//===----------------------------------------------------------------------===// 868void rdar_10640253_autorelease_allocWithZone(void) { 869 NSAutoreleasePool *pool = [[NSAutoreleasePool allocWithZone:(NSZone*)0] init]; 870 (void) pool; 871} 872 873//===----------------------------------------------------------------------===// 874// Checker should understand new/setObject:/release constructs 875//===----------------------------------------------------------------------===// 876void rdar_6866843(void) { 877 NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 878 NSMutableDictionary* dictionary = [[NSMutableDictionary alloc] init]; 879 NSArray* array = [[NSArray alloc] init]; 880 [dictionary setObject:array forKey:@"key"]; 881 [array release]; 882 // Using 'array' here should be fine 883 NSLog(@"array = %@\n", array); // no-warning 884 // Now the array is released 885 [dictionary release]; 886 [pool drain]; 887} 888 889 890//===----------------------------------------------------------------------===// 891// Classes typedef-ed to CF objects should get the same treatment as CF objects 892//===----------------------------------------------------------------------===// 893 894typedef CFTypeRef OtherRef; 895 896@interface RDar6877235 : NSObject {} 897- (CFTypeRef)_copyCFTypeRef; 898- (OtherRef)_copyOtherRef; 899@end 900 901@implementation RDar6877235 902- (CFTypeRef)_copyCFTypeRef { 903 return [[NSString alloc] init]; // no-warning 904} 905- (OtherRef)_copyOtherRef { 906 return [[NSString alloc] init]; // no-warning 907} 908@end 909 910//===----------------------------------------------------------------------===// 911// False positive - init method returns an object owned by caller. 912//===----------------------------------------------------------------------===// 913@interface RDar6320065 : NSObject { 914 NSString *_foo; 915} 916- (id)initReturningNewClass; 917- (id)_initReturningNewClassBad; 918- (id)initReturningNewClassBad2; 919@end 920 921@interface RDar6320065Subclass : RDar6320065 922@end 923 924@implementation RDar6320065 925- (id)initReturningNewClass { 926 [self release]; 927 self = [[RDar6320065Subclass alloc] init]; // no-warning 928 return self; 929} 930- (id)_initReturningNewClassBad { 931 [self release]; 932 [[RDar6320065Subclass alloc] init]; // expected-warning {{leak}} 933 return self; 934} 935- (id)initReturningNewClassBad2 { 936 [self release]; 937 self = [[RDar6320065Subclass alloc] init]; 938 return [self autorelease]; // expected-warning{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} 939} 940 941@end 942 943@implementation RDar6320065Subclass 944@end 945 946int RDar6320065_test(void) { 947 RDar6320065 *test = [[RDar6320065 alloc] init]; // no-warning 948 [test release]; 949 return 0; 950} 951 952//===----------------------------------------------------------------------===// 953// -awakeAfterUsingCoder: returns an owned object and claims the receiver 954//===----------------------------------------------------------------------===// 955@interface RDar7129086 : NSObject {} @end 956@implementation RDar7129086 957- (id)awakeAfterUsingCoder:(NSCoder *)aDecoder { 958 [self release]; // no-warning 959 return [NSString alloc]; // no-warning 960} 961@end 962 963//===----------------------------------------------------------------------===// 964// [NSData dataWithBytesNoCopy] does not return a retained object 965//===----------------------------------------------------------------------===// 966@interface RDar6859457 : NSObject {} 967- (NSString*) NoCopyString; 968- (NSString*) noCopyString; 969@end 970 971@implementation RDar6859457 972- (NSString*) NoCopyString { return [[NSString alloc] init]; } // expected-warning{{leak}} 973- (NSString*) noCopyString { return [[NSString alloc] init]; } // expected-warning{{leak}} 974@end 975 976void test_RDar6859457(RDar6859457 *x, void *bytes, NSUInteger dataLength) { 977 [x NoCopyString]; // expected-warning{{leak}} 978 [x noCopyString]; // expected-warning{{leak}} 979 [NSData dataWithBytesNoCopy:bytes length:dataLength]; // no-warning 980 [NSData dataWithBytesNoCopy:bytes length:dataLength freeWhenDone:1]; // no-warning 981} 982 983//===----------------------------------------------------------------------===// 984// PR 4230 - an autorelease pool is not necessarily leaked during a premature 985// return 986//===----------------------------------------------------------------------===// 987 988static void PR4230(void) 989{ 990 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // no-warning 991 NSString *object = [[[NSString alloc] init] autorelease]; // no-warning 992 return; 993} 994 995static void PR4230_new(void) 996{ 997 NSAutoreleasePool *pool = [NSAutoreleasePool new]; // no-warning 998 NSString *object = [[[NSString alloc] init] autorelease]; // no-warning 999 return; 1000} 1001 1002//===----------------------------------------------------------------------===// 1003// Method name that has a null IdentifierInfo* for its first selector slot. 1004// This test just makes sure that we handle it. 1005//===----------------------------------------------------------------------===// 1006 1007@interface TestNullIdentifier 1008@end 1009 1010@implementation TestNullIdentifier 1011+ (id):(int)x, ... { 1012 return [[NSString alloc] init]; // expected-warning{{leak}} 1013} 1014@end 1015 1016//===----------------------------------------------------------------------===// 1017// Don't flag leaks for return types that cannot be determined to be CF types. 1018//===----------------------------------------------------------------------===// 1019 1020// We don't know if 'struct s6893565' represents a Core Foundation type, so 1021// we shouldn't emit an error here. 1022typedef struct s6893565* TD6893565; 1023 1024@interface RDar6893565 {} 1025-(TD6893565)newThing; 1026@end 1027 1028@implementation RDar6893565 1029-(TD6893565)newThing { 1030 return (TD6893565) [[NSString alloc] init]; // no-warning 1031} 1032@end 1033 1034//===----------------------------------------------------------------------===// 1035// clang: false positives w/QC and CoreImage methods 1036//===----------------------------------------------------------------------===// 1037void rdar6902710(QCView *view, QCRenderer *renderer, CIContext *context, 1038 NSString *str, CIImage *img, CGRect rect, 1039 CIFormat form, CGColorSpaceRef cs) { 1040 [view createSnapshotImageOfType:str]; // expected-warning{{leak}} 1041 [renderer createSnapshotImageOfType:str]; // expected-warning{{leak}} 1042 [context createCGImage:img fromRect:rect]; // expected-warning{{leak}} 1043 [context createCGImage:img fromRect:rect format:form colorSpace:cs]; // expected-warning{{leak}} 1044} 1045 1046//===----------------------------------------------------------------------===// 1047// -[CIContext createCGLayerWithSize:info:] misinterpreted by clang scan-build 1048//===----------------------------------------------------------------------===// 1049void rdar6945561(CIContext *context, CGSize size, CFDictionaryRef d) { 1050 [context createCGLayerWithSize:size info:d]; // expected-warning{{leak}} 1051} 1052 1053//===----------------------------------------------------------------------===// 1054// Add knowledge of IOKit functions to retain/release checker. 1055//===----------------------------------------------------------------------===// 1056void IOBSDNameMatching_wrapper(mach_port_t mainPort, uint32_t options, const char * bsdName) { 1057 IOBSDNameMatching(mainPort, options, bsdName); // expected-warning{{leak}} 1058} 1059 1060void IOServiceMatching_wrapper(const char * name) { 1061 IOServiceMatching(name); // expected-warning{{leak}} 1062} 1063 1064void IOServiceNameMatching_wrapper(const char * name) { 1065 IOServiceNameMatching(name); // expected-warning{{leak}} 1066} 1067 1068CF_RETURNS_RETAINED CFDictionaryRef CreateDict(void); 1069 1070void IOServiceAddNotification_wrapper(mach_port_t mainPort, const io_name_t notificationType, 1071 mach_port_t wakePort, uintptr_t reference, io_iterator_t * notification ) { 1072 1073 CFDictionaryRef matching = CreateDict(); 1074 CFRelease(matching); 1075 IOServiceAddNotification(mainPort, notificationType, matching, // expected-warning{{used after it is released}} expected-warning{{deprecated}} 1076 wakePort, reference, notification); 1077} 1078 1079void IORegistryEntryIDMatching_wrapper(uint64_t entryID ) { 1080 IORegistryEntryIDMatching(entryID); // expected-warning{{leak}} 1081} 1082 1083void IOOpenFirmwarePathMatching_wrapper(mach_port_t mainPort, uint32_t options, 1084 const char * path) { 1085 IOOpenFirmwarePathMatching(mainPort, options, path); // expected-warning{{leak}} 1086} 1087 1088void IOServiceGetMatchingService_wrapper(mach_port_t mainPort) { 1089 CFDictionaryRef matching = CreateDict(); 1090 IOServiceGetMatchingService(mainPort, matching); 1091 CFRelease(matching); // expected-warning{{used after it is released}} 1092} 1093 1094void IOServiceGetMatchingServices_wrapper(mach_port_t mainPort, io_iterator_t *existing) { 1095 CFDictionaryRef matching = CreateDict(); 1096 IOServiceGetMatchingServices(mainPort, matching, existing); 1097 CFRelease(matching); // expected-warning{{used after it is released}} 1098} 1099 1100void IOServiceAddMatchingNotification_wrapper(IONotificationPortRef notifyPort, const io_name_t notificationType, 1101 IOServiceMatchingCallback callback, void * refCon, io_iterator_t * notification) { 1102 1103 CFDictionaryRef matching = CreateDict(); 1104 IOServiceAddMatchingNotification(notifyPort, notificationType, matching, callback, refCon, notification); 1105 CFRelease(matching); // expected-warning{{used after it is released}} 1106} 1107 1108//===----------------------------------------------------------------------===// 1109// Test of handling objects whose references "escape" to containers. 1110//===----------------------------------------------------------------------===// 1111 1112void CFDictionaryAddValue(CFMutableDictionaryRef, void *, void *); 1113 1114void rdar_6539791(CFMutableDictionaryRef y, void* key, void* val_key) { 1115 CFMutableDictionaryRef x = CFDictionaryCreateMutable(kCFAllocatorDefault, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); 1116 CFDictionaryAddValue(y, key, x); 1117 CFRelease(x); // the dictionary keeps a reference, so the object isn't deallocated yet 1118 signed z = 1; 1119 CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); 1120 if (value) { 1121 CFDictionaryAddValue(x, val_key, (void*)value); // no-warning 1122 CFRelease(value); 1123 CFDictionaryAddValue(y, val_key, (void*)value); // no-warning 1124 } 1125} 1126 1127// Same issue, except with "AppendValue" functions. 1128void rdar_6560661(CFMutableArrayRef x) { 1129 signed z = 1; 1130 CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); 1131 // CFArrayAppendValue keeps a reference to value. 1132 CFArrayAppendValue(x, value); 1133 CFRelease(value); 1134 CFRetain(value); 1135 CFRelease(value); // no-warning 1136} 1137 1138// Same issue, excwept with "CFAttributeStringSetAttribute". 1139void rdar_7152619(CFStringRef str) { 1140 CFAttributedStringRef string = CFAttributedStringCreate(kCFAllocatorDefault, str, 0); 1141 CFMutableAttributedStringRef attrString = CFAttributedStringCreateMutableCopy(kCFAllocatorDefault, 100, string); 1142 CFRelease(string); 1143 NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}} 1144 CFAttributedStringSetAttribute(attrString, CFRangeMake(0, 1), str, number); 1145 [number release]; 1146 [number retain]; 1147 CFRelease(attrString); 1148} 1149 1150//===----------------------------------------------------------------------===// 1151// Test of handling CGGradientXXX functions. 1152//===----------------------------------------------------------------------===// 1153 1154void rdar_7184450(CGContextRef myContext, CGFloat x, CGPoint myStartPoint, 1155 CGPoint myEndPoint) { 1156 size_t num_locations = 6; 1157 CGFloat locations[6] = { 0.0, 0.265, 0.28, 0.31, 0.36, 1.0 }; 1158 CGFloat components[28] = { 239.0/256.0, 167.0/256.0, 170.0/256.0, 1159 x, // Start color 1160 207.0/255.0, 39.0/255.0, 39.0/255.0, x, 1161 147.0/255.0, 21.0/255.0, 22.0/255.0, x, 1162 175.0/255.0, 175.0/255.0, 175.0/255.0, x, 1163 255.0/255.0,255.0/255.0, 255.0/255.0, x, 1164 255.0/255.0,255.0/255.0, 255.0/255.0, x 1165 }; // End color 1166 1167 CGGradientRef myGradient = 1168 CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), // expected-warning{{leak}} 1169 components, locations, num_locations); 1170 1171 CGContextDrawLinearGradient(myContext, myGradient, myStartPoint, myEndPoint, 1172 0); 1173 CGGradientRelease(myGradient); 1174} 1175 1176void rdar_7184450_pos(CGContextRef myContext, CGFloat x, CGPoint myStartPoint, 1177 CGPoint myEndPoint) { 1178 size_t num_locations = 6; 1179 CGFloat locations[6] = { 0.0, 0.265, 0.28, 0.31, 0.36, 1.0 }; 1180 CGFloat components[28] = { 239.0/256.0, 167.0/256.0, 170.0/256.0, 1181 x, // Start color 1182 207.0/255.0, 39.0/255.0, 39.0/255.0, x, 1183 147.0/255.0, 21.0/255.0, 22.0/255.0, x, 1184 175.0/255.0, 175.0/255.0, 175.0/255.0, x, 1185 255.0/255.0,255.0/255.0, 255.0/255.0, x, 1186 255.0/255.0,255.0/255.0, 255.0/255.0, x 1187 }; // End color 1188 1189 CGGradientRef myGradient = 1190 CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), components, locations, num_locations); // expected-warning 2 {{leak}} 1191 1192 CGContextDrawLinearGradient(myContext, myGradient, myStartPoint, myEndPoint, 1193 0); 1194} 1195 1196//===----------------------------------------------------------------------===// 1197// clang false positive: retained instance passed to thread in pthread_create 1198// marked as leak. 1199// 1200// Until we have full IPA, the analyzer should stop tracking the reference 1201// count of objects passed to pthread_create. 1202//===----------------------------------------------------------------------===// 1203struct _opaque_pthread_t {}; 1204struct _opaque_pthread_attr_t {}; 1205typedef struct _opaque_pthread_t *__darwin_pthread_t; 1206typedef struct _opaque_pthread_attr_t __darwin_pthread_attr_t; 1207typedef __darwin_pthread_t pthread_t; 1208typedef __darwin_pthread_attr_t pthread_attr_t; 1209typedef unsigned long __darwin_pthread_key_t; 1210typedef __darwin_pthread_key_t pthread_key_t; 1211 1212int pthread_create(pthread_t *, const pthread_attr_t *, 1213 void *(*)(void *), void *); 1214 1215int pthread_setspecific(pthread_key_t key, const void *value); 1216 1217void *rdar_7299394_start_routine(void *p) { 1218 [((id) p) release]; 1219 return 0; 1220} 1221void rdar_7299394(pthread_attr_t *attr, pthread_t *thread, void *args) { 1222 NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning 1223 pthread_create(thread, attr, rdar_7299394_start_routine, number); 1224} 1225void rdar_7299394_positive(pthread_attr_t *attr, pthread_t *thread) { 1226 NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}} 1227} 1228 1229//===----------------------------------------------------------------------===// 1230// False positive with not understanding thread local storage. 1231//===----------------------------------------------------------------------===// 1232void rdar11282706(pthread_key_t key) { 1233 NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning 1234 pthread_setspecific(key, (void*) number); 1235} 1236 1237//===----------------------------------------------------------------------===// 1238// False leak associated with call to CVPixelBufferCreateWithBytes() 1239// 1240// According to the Core Video Reference (ADC), CVPixelBufferCreateWithBytes and 1241// CVPixelBufferCreateWithPlanarBytes can release (via a callback) the 1242// pixel buffer object. These test cases show how the analyzer stops tracking 1243// the reference count for the objects passed for this argument. This 1244// could be made smarter. 1245//===----------------------------------------------------------------------===// 1246typedef int int32_t; 1247typedef UInt32 FourCharCode; 1248typedef FourCharCode OSType; 1249typedef uint64_t CVOptionFlags; 1250typedef int32_t CVReturn; 1251typedef struct __CVBuffer *CVBufferRef; 1252typedef CVBufferRef CVImageBufferRef; 1253typedef CVImageBufferRef CVPixelBufferRef; 1254typedef CVBufferRef CMTaggedBufferGroupRef; 1255typedef void (*CVPixelBufferReleaseBytesCallback)( void *releaseRefCon, const void *baseAddress ); 1256 1257extern CVReturn CVPixelBufferCreateWithBytes(CFAllocatorRef allocator, 1258 size_t width, 1259 size_t height, 1260 OSType pixelFormatType, 1261 void *baseAddress, 1262 size_t bytesPerRow, 1263 CVPixelBufferReleaseBytesCallback releaseCallback, 1264 void *releaseRefCon, 1265 CFDictionaryRef pixelBufferAttributes, 1266 CVPixelBufferRef *pixelBufferOut) ; 1267 1268typedef void (*CVPixelBufferReleasePlanarBytesCallback)( void *releaseRefCon, const void *dataPtr, size_t dataSize, size_t numberOfPlanes, const void *planeAddresses[] ); 1269 1270extern CVReturn CVPixelBufferCreateWithPlanarBytes(CFAllocatorRef allocator, 1271 size_t width, 1272 size_t height, 1273 OSType pixelFormatType, 1274 void *dataPtr, 1275 size_t dataSize, 1276 size_t numberOfPlanes, 1277 void *planeBaseAddress[], 1278 size_t planeWidth[], 1279 size_t planeHeight[], 1280 size_t planeBytesPerRow[], 1281 CVPixelBufferReleasePlanarBytesCallback releaseCallback, 1282 void *releaseRefCon, 1283 CFDictionaryRef pixelBufferAttributes, 1284 CVPixelBufferRef *pixelBufferOut) ; 1285 1286extern CVReturn CVPixelBufferCreateWithBytes(CFAllocatorRef allocator, 1287 size_t width, 1288 size_t height, 1289 OSType pixelFormatType, 1290 void *baseAddress, 1291 size_t bytesPerRow, 1292 CVPixelBufferReleaseBytesCallback releaseCallback, 1293 void *releaseRefCon, 1294 CFDictionaryRef pixelBufferAttributes, 1295 CVPixelBufferRef *pixelBufferOut) ; 1296 1297CVReturn rdar_7283567(CFAllocatorRef allocator, size_t width, size_t height, 1298 OSType pixelFormatType, void *baseAddress, 1299 size_t bytesPerRow, 1300 CVPixelBufferReleaseBytesCallback releaseCallback, 1301 CFDictionaryRef pixelBufferAttributes, 1302 CVPixelBufferRef *pixelBufferOut) { 1303 1304 // For the allocated object, it doesn't really matter what type it is 1305 // for the purpose of this test. All we want to show is that 1306 // this is freed later by the callback. 1307 NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning 1308 1309 return CVPixelBufferCreateWithBytes(allocator, width, height, pixelFormatType, 1310 baseAddress, bytesPerRow, releaseCallback, 1311 number, // potentially released by callback 1312 pixelBufferAttributes, pixelBufferOut) ; 1313} 1314 1315CVReturn rdar_7283567_2(CFAllocatorRef allocator, size_t width, size_t height, 1316 OSType pixelFormatType, void *dataPtr, size_t dataSize, 1317 size_t numberOfPlanes, void *planeBaseAddress[], 1318 size_t planeWidth[], size_t planeHeight[], size_t planeBytesPerRow[], 1319 CVPixelBufferReleasePlanarBytesCallback releaseCallback, 1320 CFDictionaryRef pixelBufferAttributes, 1321 CVPixelBufferRef *pixelBufferOut) { 1322 1323 // For the allocated object, it doesn't really matter what type it is 1324 // for the purpose of this test. All we want to show is that 1325 // this is freed later by the callback. 1326 NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning 1327 1328 return CVPixelBufferCreateWithPlanarBytes(allocator, 1329 width, height, pixelFormatType, dataPtr, dataSize, 1330 numberOfPlanes, planeBaseAddress, planeWidth, 1331 planeHeight, planeBytesPerRow, releaseCallback, 1332 number, // potentially released by callback 1333 pixelBufferAttributes, pixelBufferOut) ; 1334} 1335 1336#pragma clang arc_cf_code_audited begin 1337typedef struct SomeOpaqueStruct *CMSampleBufferRef; 1338CVImageBufferRef _Nonnull CMSampleBufferGetImageBuffer(CMSampleBufferRef _Nonnull sbuf); 1339#pragma clang arc_cf_code_audited end 1340 1341CVBufferRef _Nullable CVBufferRetain(CVBufferRef _Nullable buffer); 1342void CVBufferRelease(CF_CONSUMED CVBufferRef _Nullable buffer); 1343 1344void testCVPrefixRetain(CMSampleBufferRef sbuf) { 1345 // Make sure RetainCountChecker treats CVFooRetain() as a CF-style retain. 1346 CVPixelBufferRef pixelBuf = CMSampleBufferGetImageBuffer(sbuf); 1347 CVBufferRetain(pixelBuf); 1348 CVBufferRelease(pixelBuf); // no-warning 1349 1350 1351 // Make sure result of CVFooRetain() is the same as its argument. 1352 CVPixelBufferRef pixelBufAlias = CVBufferRetain(pixelBuf); 1353 CVBufferRelease(pixelBufAlias); // no-warning 1354} 1355 1356typedef signed long SInt32; 1357typedef SInt32 OSStatus; 1358typedef FourCharCode CMVideoCodecType; 1359 1360 1361typedef UInt32 VTEncodeInfoFlags; enum { 1362 kVTEncodeInfo_Asynchronous = 1UL << 0, 1363 kVTEncodeInfo_FrameDropped = 1UL << 1, 1364}; 1365typedef struct 1366{ 1367 int ignore; 1368} CMTime; 1369 1370 1371typedef void (*VTCompressionOutputCallback)( 1372 void * _Nullable outputCallbackRefCon, 1373 void * _Nullable sourceFrameRefCon, 1374 OSStatus status, 1375 VTEncodeInfoFlags infoFlags, 1376 _Nullable CMSampleBufferRef sampleBuffer ); 1377 1378typedef struct OpaqueVTCompressionSession* VTCompressionSessionRef; 1379 1380extern OSStatus 1381VTCompressionSessionCreate(_Nullable CFAllocatorRef allocator, 1382 int32_t width, 1383 int32_t height, 1384 CMVideoCodecType codecType, 1385 _Nullable CFDictionaryRef encoderSpecification, 1386 _Nullable CFDictionaryRef sourceImageBufferAttributes, 1387 _Nullable CFAllocatorRef compressedDataAllocator, 1388 _Nullable VTCompressionOutputCallback outputCallback, 1389 void * _Nullable outputCallbackRefCon, 1390 CF_RETURNS_RETAINED _Nullable VTCompressionSessionRef * _Nonnull compressionSessionOut); 1391 1392extern OSStatus 1393VTCompressionSessionEncodeFrame( 1394 _Nonnull VTCompressionSessionRef session, 1395 _Nonnull CVImageBufferRef imageBuffer, 1396 CMTime presentationTimeStamp, 1397 CMTime duration, 1398 _Nullable CFDictionaryRef frameProperties, 1399 void * _Nullable sourceFrameRefCon, 1400 VTEncodeInfoFlags * _Nullable infoFlagsOut); 1401 1402extern OSStatus 1403VTCompressionSessionEncodeMultiImageFrame( 1404 _Nonnull VTCompressionSessionRef session, 1405 _Nonnull CVImageBufferRef imageBuffer, 1406 CMTime presentationTimeStamp, 1407 CMTime duration, 1408 _Nullable CFDictionaryRef frameProperties, 1409 void * _Nullable sourceFrameRefCon, 1410 VTEncodeInfoFlags * _Nullable infoFlagsOut); 1411 1412OSStatus test_VTCompressionSessionCreateAndEncode_CallbackReleases( 1413 _Nullable CFAllocatorRef allocator, 1414 int32_t width, 1415 int32_t height, 1416 CMVideoCodecType codecType, 1417 _Nullable CFDictionaryRef encoderSpecification, 1418 _Nullable CFDictionaryRef sourceImageBufferAttributes, 1419 _Nullable CFAllocatorRef compressedDataAllocator, 1420 _Nullable VTCompressionOutputCallback outputCallback, 1421 1422 _Nonnull CVImageBufferRef imageBuffer, 1423 CMTime presentationTimeStamp, 1424 CMTime duration, 1425 _Nullable CFDictionaryRef frameProperties 1426) { 1427 1428 // The outputCallback is passed both contexts and so can release either. 1429 NSNumber *contextForCreate = [[NSNumber alloc] initWithInt:5]; // no-warning 1430 NSNumber *contextForEncode = [[NSNumber alloc] initWithInt:6]; // no-warning 1431 NSNumber *contextForEncodeMultiFrame = [[NSNumber alloc] initWithInt:7]; // no-warning 1432 1433 1434 VTCompressionSessionRef session = 0; 1435 OSStatus status = VTCompressionSessionCreate(allocator, 1436 width, height, codecType, encoderSpecification, 1437 sourceImageBufferAttributes, 1438 compressedDataAllocator, outputCallback, contextForCreate, 1439 &session); 1440 1441 VTEncodeInfoFlags encodeInfoFlags; 1442 1443 status = VTCompressionSessionEncodeFrame(session, imageBuffer, 1444 presentationTimeStamp, duration, frameProperties, contextForEncode, 1445 &encodeInfoFlags); 1446 1447 status = VTCompressionSessionEncodeMultiImageFrame(session, imageBuffer, 1448 presentationTimeStamp, duration, frameProperties, contextForEncodeMultiFrame, 1449 &encodeInfoFlags); 1450 1451 return status; 1452} 1453 1454//===----------------------------------------------------------------------===// 1455// False leak associated with CGBitmapContextCreateWithData. 1456//===----------------------------------------------------------------------===// 1457typedef uint32_t CGBitmapInfo; 1458typedef void (*CGBitmapContextReleaseDataCallback)(void *releaseInfo, void *data); 1459 1460CGContextRef CGBitmapContextCreateWithData(void *data, 1461 size_t width, size_t height, size_t bitsPerComponent, 1462 size_t bytesPerRow, CGColorSpaceRef space, CGBitmapInfo bitmapInfo, 1463 CGBitmapContextReleaseDataCallback releaseCallback, void *releaseInfo); 1464 1465void rdar_7358899(void *data, 1466 size_t width, size_t height, size_t bitsPerComponent, 1467 size_t bytesPerRow, CGColorSpaceRef space, CGBitmapInfo bitmapInfo, 1468 CGBitmapContextReleaseDataCallback releaseCallback) { 1469 1470 // For the allocated object, it doesn't really matter what type it is 1471 // for the purpose of this test. All we want to show is that 1472 // this is freed later by the callback. 1473 NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning 1474 1475 CGBitmapContextCreateWithData(data, width, height, bitsPerComponent, // expected-warning{{leak}} 1476 bytesPerRow, space, bitmapInfo, releaseCallback, number); 1477} 1478 1479//===----------------------------------------------------------------------===// 1480// Allow 'new', 'copy', 'alloc', 'init' prefix to start before '_' when 1481// determining Cocoa fundamental rule. 1482// 1483// Previously the retain/release checker just skipped prefixes before the 1484// first '_' entirely. Now the checker honors the prefix if it results in a 1485// recognizable naming convention (e.g., 'new', 'init'). 1486//===----------------------------------------------------------------------===// 1487@interface RDar7265711 {} 1488- (id) new_stuff; 1489@end 1490 1491void rdar7265711_a(RDar7265711 *x) { 1492 id y = [x new_stuff]; // expected-warning{{leak}} 1493} 1494 1495void rdar7265711_b(RDar7265711 *x) { 1496 id y = [x new_stuff]; // no-warning 1497 [y release]; 1498} 1499 1500//===----------------------------------------------------------------------===// 1501// clang thinks [NSCursor dragCopyCursor] returns a retained reference. 1502//===----------------------------------------------------------------------===// 1503@interface NSCursor : NSObject 1504+ (NSCursor *)dragCopyCursor; 1505@end 1506 1507void rdar7306898(void) { 1508 // 'dragCopyCursor' does not follow Cocoa's fundamental rule. It is a noun, not an sentence 1509 // implying a 'copy' of something. 1510 NSCursor *c = [NSCursor dragCopyCursor]; // no-warning 1511 NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}} 1512} 1513 1514//===----------------------------------------------------------------------===// 1515// Sending 'release', 'retain', etc. to a Class directly is not likely what the 1516// user intended. 1517//===----------------------------------------------------------------------===// 1518@interface RDar7252064 : NSObject @end 1519void rdar7252064(void) { 1520 [RDar7252064 release]; // expected-warning{{The 'release' message should be sent to instances of class 'RDar7252064' and not the class directly}} 1521 [RDar7252064 retain]; // expected-warning{{The 'retain' message should be sent to instances of class 'RDar7252064' and not the class directly}} 1522 [RDar7252064 autorelease]; // expected-warning{{The 'autorelease' message should be sent to instances of class 'RDar7252064' and not the class directly}} 1523 [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}} 1524} 1525 1526//===----------------------------------------------------------------------===// 1527// Tests of ownership attributes. 1528//===----------------------------------------------------------------------===// 1529 1530typedef NSString* MyStringTy; 1531 1532@protocol FooP; 1533 1534@interface TestOwnershipAttr : NSObject 1535- (NSString*) returnsAnOwnedString NS_RETURNS_RETAINED; // no-warning 1536- (NSString*) returnsAnOwnedCFString CF_RETURNS_RETAINED; // no-warning 1537- (MyStringTy) returnsAnOwnedTypedString NS_RETURNS_RETAINED; // no-warning 1538- (NSString*) newString NS_RETURNS_NOT_RETAINED; // no-warning 1539- (NSString*) newString_auto NS_RETURNS_AUTORELEASED; // no-warning 1540- (NSString*) newStringNoAttr; 1541- (int) returnsAnOwnedInt NS_RETURNS_RETAINED; // expected-warning{{'ns_returns_retained' attribute only applies to methods that return an Objective-C object}} 1542- (id) pseudoInit NS_CONSUMES_SELF NS_RETURNS_RETAINED; 1543+ (void) consume:(id) NS_CONSUMED x; 1544+ (void) consume2:(id) CF_CONSUMED x; 1545@end 1546 1547static int ownership_attribute_doesnt_go_here NS_RETURNS_RETAINED; // expected-warning{{'ns_returns_retained' only applies to function types; type here is 'int'}} 1548 1549void test_attr_1(TestOwnershipAttr *X) { 1550 NSString *str = [X returnsAnOwnedString]; // expected-warning{{leak}} 1551} 1552 1553void test_attr_1b(TestOwnershipAttr *X) { 1554 NSString *str = [X returnsAnOwnedCFString]; // expected-warning{{leak}} 1555} 1556 1557void test_attr1c(TestOwnershipAttr *X) { 1558 NSString *str = [X newString]; // no-warning 1559 NSString *str2 = [X newStringNoAttr]; // expected-warning{{leak}} 1560 NSString *str3 = [X newString_auto]; // no-warning 1561 NSString *str4 = [[X newString_auto] retain]; // expected-warning {{leak}} 1562} 1563 1564void testattr2_a(void) { 1565 TestOwnershipAttr *x = [TestOwnershipAttr alloc]; // expected-warning{{leak}} 1566} 1567 1568void testattr2_b(void) { 1569 TestOwnershipAttr *x = [[TestOwnershipAttr alloc] pseudoInit]; // expected-warning{{leak}} 1570} 1571 1572void testattr2_b_11358224_self_assign_looses_the_leak(void) { 1573 TestOwnershipAttr *x = [[TestOwnershipAttr alloc] pseudoInit];// expected-warning{{leak}} 1574 x = x; 1575} 1576 1577void testattr2_c(void) { 1578 TestOwnershipAttr *x = [[TestOwnershipAttr alloc] pseudoInit]; // no-warning 1579 [x release]; 1580} 1581 1582void testattr3(void) { 1583 TestOwnershipAttr *x = [TestOwnershipAttr alloc]; // no-warning 1584 [TestOwnershipAttr consume:x]; 1585 TestOwnershipAttr *y = [TestOwnershipAttr alloc]; // no-warning 1586 [TestOwnershipAttr consume2:y]; 1587} 1588 1589void consume_ns(id NS_CONSUMED x); 1590void consume_cf(id CF_CONSUMED x); 1591 1592void testattr4(void) { 1593 TestOwnershipAttr *x = [TestOwnershipAttr alloc]; // no-warning 1594 consume_ns(x); 1595 TestOwnershipAttr *y = [TestOwnershipAttr alloc]; // no-warning 1596 consume_cf(y); 1597} 1598 1599@interface TestOwnershipAttr2 : NSObject 1600- (NSString*) newString NS_RETURNS_NOT_RETAINED; // no-warning 1601@end 1602 1603@implementation TestOwnershipAttr2 1604- (NSString*) newString { 1605 return [NSString alloc]; // expected-warning {{Potential leak of an object}} 1606} 1607@end 1608 1609@interface MyClassTestCFAttr : NSObject {} 1610- (NSDate*) returnsCFRetained CF_RETURNS_RETAINED; 1611- (CFDateRef) returnsCFRetainedAsCF CF_RETURNS_RETAINED; 1612- (CFDateRef) newCFRetainedAsCF CF_RETURNS_NOT_RETAINED; 1613- (CFDateRef) newCFRetainedAsCFNoAttr; 1614- (NSDate*) alsoReturnsRetained; 1615- (CFDateRef) alsoReturnsRetainedAsCF; 1616- (NSDate*) returnsNSRetained NS_RETURNS_RETAINED; 1617@end 1618 1619CF_RETURNS_RETAINED 1620CFDateRef returnsRetainedCFDate(void) { 1621 return CFDateCreate(0, CFAbsoluteTimeGetCurrent()); 1622} 1623 1624@implementation MyClassTestCFAttr 1625- (NSDate*) returnsCFRetained { 1626 return (NSDate*) returnsRetainedCFDate(); // No leak. 1627} 1628 1629- (CFDateRef) returnsCFRetainedAsCF { 1630 return returnsRetainedCFDate(); // No leak. 1631} 1632 1633- (CFDateRef) newCFRetainedAsCF { 1634 return (CFDateRef)[(id)[self returnsCFRetainedAsCF] autorelease]; 1635} 1636 1637- (CFDateRef) newCFRetainedAsCFNoAttr { 1638 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}} 1639} 1640 1641- (NSDate*) alsoReturnsRetained { 1642 return (NSDate*) returnsRetainedCFDate(); // expected-warning{{leak}} 1643} 1644 1645- (CFDateRef) alsoReturnsRetainedAsCF { 1646 return returnsRetainedCFDate(); // expected-warning{{leak}} 1647} 1648 1649 1650- (NSDate*) returnsNSRetained { 1651 return (NSDate*) returnsRetainedCFDate(); // no-warning 1652} 1653@end 1654 1655//===----------------------------------------------------------------------===// 1656// Test that leaks post-dominated by "panic" functions are not reported. 1657// 1658// Do not report a leak when post-dominated by a call to a noreturn or panic 1659// function. 1660//===----------------------------------------------------------------------===// 1661void panic(void) __attribute__((noreturn)); 1662void panic_not_in_hardcoded_list(void) __attribute__((noreturn)); 1663 1664void test_panic_negative(void) { 1665 signed z = 1; 1666 CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // expected-warning{{leak}} 1667} 1668 1669void test_panic_positive(void) { 1670 signed z = 1; 1671 CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // no-warning 1672 panic(); 1673} 1674 1675void test_panic_neg_2(int x) { 1676 signed z = 1; 1677 CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // expected-warning{{leak}} 1678 if (x) 1679 panic(); 1680} 1681 1682void test_panic_pos_2(int x) { 1683 signed z = 1; 1684 CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // no-warning 1685 if (x) 1686 panic(); 1687 if (!x) { 1688 // This showed up previously where we silently missed checking the function 1689 // type for noreturn. "panic()" is a hard-coded known panic function that 1690 // isn't always noreturn. 1691 panic_not_in_hardcoded_list(); 1692 } 1693} 1694 1695//===----------------------------------------------------------------------===// 1696// Test uses of blocks (closures) 1697//===----------------------------------------------------------------------===// 1698 1699void test_blocks_1_pos(void) { 1700 NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}} 1701 ^{}(); 1702} 1703 1704void test_blocks_1_indirect_release(void) { 1705 NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning 1706 ^{ [number release]; }(); 1707} 1708 1709void test_blocks_1_indirect_retain(void) { 1710 // Eventually this should be reported as a leak. 1711 NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning 1712 ^{ [number retain]; }(); 1713} 1714 1715void test_blocks_1_indirect_release_via_call(void) { 1716 NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning 1717 ^(NSObject *o){ [o release]; }(number); 1718} 1719 1720void test_blocks_1_indirect_retain_via_call(void) { 1721 NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning {{leak}} 1722 ^(NSObject *o){ [o retain]; }(number); 1723} 1724 1725//===--------------------------------------------------------------------===// 1726// Test sending message to super that returns an object alias. Previously 1727// this caused a crash in the analyzer. 1728//===--------------------------------------------------------------------===// 1729 1730@interface Rdar8015556 : NSObject {} @end 1731@implementation Rdar8015556 1732- (id)retain { 1733 return [super retain]; 1734} 1735@end 1736 1737// Correcly handle Class<...> in Cocoa Conventions detector. 1738@protocol Prot_R8272168 @end 1739Class <Prot_R8272168> GetAClassThatImplementsProt_R8272168(void); 1740void r8272168(void) { 1741 GetAClassThatImplementsProt_R8272168(); 1742} 1743 1744// This used to trigger a false positive. 1745@interface RDar8356342 1746- (NSDate*) rdar8356342:(NSDate *)inValue; 1747@end 1748 1749@implementation RDar8356342 1750- (NSDate*) rdar8356342:(NSDate*)inValue { 1751 NSDate *outValue = inValue; 1752 if (outValue == 0) 1753 outValue = [[NSDate alloc] init]; // no-warning 1754 1755 if (outValue != inValue) 1756 [outValue autorelease]; 1757 1758 return outValue; 1759} 1760@end 1761 1762// This test case previously crashed because of a bug in BugReporter. 1763extern const void *CFDictionaryGetValue(CFDictionaryRef theDict, const void *key); 1764typedef struct __CFError * CFErrorRef; 1765extern const CFStringRef kCFErrorUnderlyingErrorKey; 1766extern CFDictionaryRef CFErrorCopyUserInfo(CFErrorRef err); 1767static void rdar_8724287(CFErrorRef error) 1768{ 1769 CFErrorRef error_to_dump; 1770 1771 error_to_dump = error; 1772 while (error_to_dump != ((void*)0)) { 1773 CFDictionaryRef info; 1774 1775 info = CFErrorCopyUserInfo(error_to_dump); // expected-warning{{Potential leak of an object}} 1776 1777 if (info != ((void*)0)) { 1778 } 1779 1780 error_to_dump = (CFErrorRef) CFDictionaryGetValue(info, kCFErrorUnderlyingErrorKey); 1781 } 1782} 1783 1784// Make sure the model applies cf_consumed correctly in argument positions 1785// besides the first. 1786extern void *CFStringCreate(void); 1787extern void rdar_9234108_helper(void *key, void * CF_CONSUMED value); 1788void rdar_9234108(void) { 1789 rdar_9234108_helper(0, CFStringCreate()); 1790} 1791 1792// Make sure that objc_method_family works to override naming conventions. 1793struct TwoDoubles { 1794 double one; 1795 double two; 1796}; 1797typedef struct TwoDoubles TwoDoubles; 1798 1799@interface NSValue (Mine) 1800- (id)_prefix_initWithTwoDoubles:(TwoDoubles)twoDoubles __attribute__((objc_method_family(init))); 1801@end 1802 1803@implementation NSValue (Mine) 1804- (id)_prefix_initWithTwoDoubles:(TwoDoubles)twoDoubles 1805{ 1806 return [self init]; 1807} 1808@end 1809 1810void rdar9726279(void) { 1811 TwoDoubles twoDoubles = { 0.0, 0.0 }; 1812 NSValue *value = [[NSValue alloc] _prefix_initWithTwoDoubles:twoDoubles]; 1813 [value release]; 1814} 1815 1816// Test camelcase support for CF conventions. While Core Foundation APIs 1817// don't use camel casing, other code is allowed to use it. 1818CFArrayRef camelcase_create_1(void) { 1819 return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning 1820} 1821 1822CFArrayRef camelcase_createno(void) { 1823 return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning {{leak}} 1824} 1825 1826CFArrayRef camelcase_copy(void) { 1827 return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning 1828} 1829 1830CFArrayRef camelcase_copying(void) { 1831 return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning {{leak}} 1832} 1833 1834CFArrayRef copyCamelCase(void) { 1835 return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning 1836} 1837 1838CFArrayRef __copyCamelCase(void) { 1839 return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning 1840} 1841 1842CFArrayRef __createCamelCase(void) { 1843 return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning 1844} 1845 1846CFArrayRef camel_create(void) { 1847 return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning 1848} 1849 1850 1851CFArrayRef camel_creat(void) { 1852 return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning {{leak}} 1853} 1854 1855CFArrayRef camel_copy(void) { 1856 return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning 1857} 1858 1859CFArrayRef camel_copyMachine(void) { 1860 return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning 1861} 1862 1863CFArrayRef camel_copymachine(void) { 1864 return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning {{leak}} 1865} 1866 1867@protocol F18P 1868- (id) clone; // expected-note 2 {{method declared here}} 1869@end 1870@interface F18 : NSObject<F18P> @end 1871@interface F18(Cat) 1872- (id) clone NS_RETURNS_RETAINED; // expected-warning {{overriding method has mismatched ns_returns_retained attributes}} 1873@end 1874 1875@implementation F18 1876- (id) clone { // expected-warning {{overriding method has mismatched ns_returns_retained attributes}} 1877 return [F18 alloc]; 1878} 1879@end 1880 1881void rdar6582778(void) { 1882 CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); 1883 CFTypeRef vals[] = { CFDateCreate(0, t) }; // expected-warning {{leak}} 1884} 1885 1886CFTypeRef global; 1887 1888void rdar6582778_2(void) { 1889 CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); 1890 global = CFDateCreate(0, t); // no-warning 1891} 1892 1893// Test that objects passed to containers are marked "escaped". 1894void rdar10232019(void) { 1895 NSMutableArray *array = [NSMutableArray array]; 1896 1897 NSString *string = [[NSString alloc] initWithUTF8String:"foo"]; 1898 [array addObject:string]; 1899 [string release]; 1900 1901 NSString *otherString = [string stringByAppendingString:@"bar"]; // no-warning 1902 NSLog(@"%@", otherString); 1903} 1904 1905void rdar10232019_positive(void) { 1906 NSMutableArray *array = [NSMutableArray array]; 1907 1908 NSString *string = [[NSString alloc] initWithUTF8String:"foo"]; 1909 [string release]; 1910 1911 NSString *otherString = [string stringByAppendingString:@"bar"]; // expected-warning {{Reference-counted object is used after it is release}} 1912 NSLog(@"%@", otherString); 1913} 1914 1915// RetainCountChecker support for XPC. 1916typedef void * xpc_object_t; 1917xpc_object_t _CFXPCCreateXPCObjectFromCFObject(CFTypeRef cf); 1918void xpc_release(xpc_object_t object); 1919 1920void rdar9658496(void) { 1921 CFStringRef cf; 1922 xpc_object_t xpc; 1923 cf = CFStringCreateWithCString( ((CFAllocatorRef)0), "test", kCFStringEncodingUTF8 ); // no-warning 1924 xpc = _CFXPCCreateXPCObjectFromCFObject( cf ); 1925 CFRelease(cf); 1926 xpc_release(xpc); 1927} 1928 1929// Support annotations with method families. 1930@interface RDar10824732 : NSObject 1931- (id)initWithObj:(id CF_CONSUMED)obj; 1932@end 1933 1934@implementation RDar10824732 1935- (id)initWithObj:(id)obj { 1936 [obj release]; 1937 return [super init]; 1938} 1939@end 1940 1941void rdar_10824732(void) { 1942 @autoreleasepool { 1943 NSString *obj = @"test"; 1944 RDar10824732 *foo = [[RDar10824732 alloc] initWithObj:obj]; // no-warning 1945 [foo release]; 1946 } 1947} 1948 1949// Stop tracking objects passed to functions, which take callbacks as parameters. 1950typedef int (*CloseCallback) (void *); 1951void ReaderForIO(CloseCallback ioclose, void *ioctx); 1952int IOClose(void *context); 1953 1954@protocol SInS <NSObject> 1955@end 1956 1957@interface radar10973977 : NSObject 1958- (id<SInS>)inputS; 1959- (void)reader; 1960@end 1961 1962@implementation radar10973977 1963- (void)reader 1964{ 1965 id<SInS> inputS = [[self inputS] retain]; 1966 ReaderForIO(IOClose, inputS); 1967} 1968- (id<SInS>)inputS 1969{ 1970 return 0; 1971} 1972@end 1973 1974// Object escapes through a selector callback 1975extern id NSApp; 1976@interface MySheetController 1977- (id<SInS>)inputS; 1978- (void)showDoSomethingSheetAction:(id)action; 1979- (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo; 1980@end 1981 1982@implementation MySheetController 1983- (id<SInS>)inputS { 1984 return 0; 1985} 1986- (void)showDoSomethingSheetAction:(id)action { 1987 id<SInS> inputS = [[self inputS] retain]; 1988 [NSApp beginSheet:0 1989 modalForWindow:0 1990 modalDelegate:0 1991 didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) 1992 contextInfo:(void *)inputS]; // no - warning 1993} 1994- (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo { 1995 1996 id contextObject = (id)contextInfo; 1997 [contextObject release]; 1998} 1999 2000- (id)copyAutoreleaseRadar13081402 { 2001 id x = [[[NSString alloc] initWithUTF8String:"foo"] autorelease]; 2002 [x retain]; 2003 return x; // no warning 2004} 2005 2006@end 2007//===----------------------------------------------------------------------===// 2008// Test returning allocated memory in a struct. 2009// 2010// We currently don't have a general way to track pointers that "escape". 2011// Here we test that RetainCountChecker doesn't get excited about returning 2012// allocated CF objects in struct fields. 2013//===----------------------------------------------------------------------===// 2014void *malloc(size_t); 2015struct rdar11104566 { CFStringRef myStr; }; 2016struct rdar11104566 test_rdar11104566(void) { 2017 CFStringRef cf = CFStringCreateWithCString( ((CFAllocatorRef)0), "test", kCFStringEncodingUTF8 ); // no-warning 2018 struct rdar11104566 V; 2019 V.myStr = cf; 2020 return V; // no-warning 2021} 2022 2023struct rdar11104566 *test_2_rdar11104566(void) { 2024 CFStringRef cf = CFStringCreateWithCString( ((CFAllocatorRef)0), "test", kCFStringEncodingUTF8 ); // no-warning 2025 struct rdar11104566 *V = (struct rdar11104566 *) malloc(sizeof(*V)); 2026 V->myStr = cf; 2027 return V; // no-warning 2028} 2029 2030//===----------------------------------------------------------------------===// 2031// ObjC literals support. 2032//===----------------------------------------------------------------------===// 2033 2034void test_objc_arrays(void) { 2035 { // CASE ONE -- OBJECT IN ARRAY CREATED DIRECTLY 2036 NSObject *o = [[NSObject alloc] init]; 2037 NSArray *a = [[NSArray alloc] initWithObjects:o, (void*)0]; // expected-warning {{leak}} 2038 [o release]; 2039 [a description]; 2040 [o description]; 2041 } 2042 2043 { // CASE TWO -- OBJECT IN ARRAY CREATED BY DUPING AUTORELEASED ARRAY 2044 NSObject *o = [[NSObject alloc] init]; 2045 NSArray *a1 = [NSArray arrayWithObjects:o, (void*)0]; 2046 NSArray *a2 = [[NSArray alloc] initWithArray:a1]; // expected-warning {{leak}} 2047 [o release]; 2048 [a2 description]; 2049 [o description]; 2050 } 2051 2052 { // CASE THREE -- OBJECT IN RETAINED @[] 2053 NSObject *o = [[NSObject alloc] init]; 2054 NSArray *a3 = [@[o] retain]; // expected-warning {{leak}} 2055 [o release]; 2056 [a3 description]; 2057 [o description]; 2058 } 2059 2060 { // CASE FOUR -- OBJECT IN ARRAY CREATED BY DUPING @[] 2061 NSObject *o = [[NSObject alloc] init]; 2062 NSArray *a = [[NSArray alloc] initWithArray:@[o]]; // expected-warning {{leak}} 2063 [o release]; 2064 2065 [a description]; 2066 [o description]; 2067 } 2068 2069 { // CASE FIVE -- OBJECT IN RETAINED @{} 2070 NSValue *o = [[NSValue alloc] init]; 2071 NSDictionary *a = [@{o : o} retain]; // expected-warning {{leak}} 2072 [o release]; 2073 2074 [a description]; 2075 [o description]; 2076 } 2077} 2078 2079void test_objc_integer_literals(void) { 2080 id value = [@1 retain]; // expected-warning {{leak}} 2081 [value description]; 2082} 2083 2084void test_objc_boxed_expressions(int x, const char *y) { 2085 id value = [@(x) retain]; // expected-warning {{leak}} 2086 [value description]; 2087 2088 value = [@(y) retain]; // expected-warning {{leak}} 2089 [value description]; 2090} 2091 2092// Test NSLog doesn't escape tracked objects. 2093void rdar11400885(int y) 2094{ 2095 @autoreleasepool { 2096 NSString *printString; 2097 if(y > 2) 2098 printString = [[NSString alloc] init]; 2099 else 2100 printString = [[NSString alloc] init]; 2101 NSLog(@"Once %@", printString); 2102 [printString release]; 2103 NSLog(@"Again: %@", printString); // expected-warning {{Reference-counted object is used after it is released}} 2104 } 2105} 2106 2107id makeCollectableNonLeak(void) { 2108 extern CFTypeRef CFCreateSomething(void); 2109 2110 CFTypeRef object = CFCreateSomething(); // +1 2111 CFRetain(object); // +2 2112 id objCObject = NSMakeCollectable(object); // +2 2113 [objCObject release]; // +1 2114 return [objCObject autorelease]; // +0 2115} 2116 2117void consumeAndStopTracking(id NS_CONSUMED obj, void (^callback)(void)); 2118void CFConsumeAndStopTracking(CFTypeRef CF_CONSUMED obj, void (^callback)(void)); 2119 2120void testConsumeAndStopTracking(void) { 2121 id retained = [@[] retain]; // +1 2122 consumeAndStopTracking(retained, ^{}); // no-warning 2123 2124 id doubleRetained = [[@[] retain] retain]; // +2 2125 consumeAndStopTracking(doubleRetained, ^{ 2126 [doubleRetained release]; 2127 }); // no-warning 2128 2129 id unretained = @[]; // +0 2130 consumeAndStopTracking(unretained, ^{}); // expected-warning {{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} 2131} 2132 2133void testCFConsumeAndStopTracking(void) { 2134 id retained = [@[] retain]; // +1 2135 CFConsumeAndStopTracking((CFTypeRef)retained, ^{}); // no-warning 2136 2137 id doubleRetained = [[@[] retain] retain]; // +2 2138 CFConsumeAndStopTracking((CFTypeRef)doubleRetained, ^{ 2139 [doubleRetained release]; 2140 }); // no-warning 2141 2142 id unretained = @[]; // +0 2143 CFConsumeAndStopTracking((CFTypeRef)unretained, ^{}); // expected-warning {{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} 2144} 2145//===----------------------------------------------------------------------===// 2146// Test 'pragma clang arc_cf_code_audited' support. 2147//===----------------------------------------------------------------------===// 2148 2149typedef void *MyCFType; 2150#pragma clang arc_cf_code_audited begin 2151MyCFType CreateMyCFType(void); 2152#pragma clang arc_cf_code_audited end 2153 2154void test_custom_cf(void) { 2155 MyCFType x = CreateMyCFType(); // expected-warning {{leak of an object stored into 'x'}} 2156} 2157 2158//===----------------------------------------------------------------------===// 2159// Test calling CFPlugInInstanceCreate, which appears in CF but doesn't 2160// return a CF object. 2161//===----------------------------------------------------------------------===// 2162 2163void test_CFPlugInInstanceCreate(CFUUIDRef factoryUUID, CFUUIDRef typeUUID) { 2164 CFPlugInInstanceCreate(kCFAllocatorDefault, factoryUUID, typeUUID); // no-warning 2165} 2166 2167//===----------------------------------------------------------------------===// 2168// PR14927: -drain only has retain-count semantics on NSAutoreleasePool. 2169//===----------------------------------------------------------------------===// 2170 2171@interface PR14927 : NSObject 2172- (void)drain; 2173@end 2174 2175void test_drain(void) { 2176 PR14927 *obj = [[PR14927 alloc] init]; 2177 [obj drain]; 2178 [obj release]; // no-warning 2179} 2180 2181//===----------------------------------------------------------------------===// 2182// Allow cf_returns_retained and cf_returns_not_retained to mark a return 2183// value as tracked, even if the object isn't a known CF type. 2184//===----------------------------------------------------------------------===// 2185 2186MyCFType getCustom(void) __attribute__((cf_returns_not_retained)); 2187MyCFType makeCustom(void) __attribute__((cf_returns_retained)); 2188 2189void testCustomReturnsRetained(void) { 2190 MyCFType obj = makeCustom(); // expected-warning {{leak of an object stored into 'obj'}} 2191} 2192 2193void testCustomReturnsNotRetained(void) { 2194 CFRelease(getCustom()); // expected-warning {{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} 2195} 2196 2197//===----------------------------------------------------------------------===// 2198// Don't print variables which are out of the current scope. 2199//===----------------------------------------------------------------------===// 2200@interface MyObj12706177 : NSObject 2201-(id)initX; 2202+(void)test12706177; 2203@end 2204static int Cond; 2205@implementation MyObj12706177 2206-(id)initX { 2207 if (Cond) 2208 return 0; 2209 self = [super init]; 2210 return self; 2211} 2212+(void)test12706177 { 2213 id x = [[MyObj12706177 alloc] initX]; //expected-warning {{Potential leak of an object}} 2214 [x release]; 2215} 2216@end 2217 2218//===----------------------------------------------------------------------===// 2219// CFAutorelease 2220//===----------------------------------------------------------------------===// 2221 2222CFTypeRef getAutoreleasedCFType(void) { 2223 extern CFTypeRef CFCreateSomething(void); 2224 return CFAutorelease(CFCreateSomething()); // no-warning 2225} 2226 2227CFTypeRef getIncorrectlyAutoreleasedCFType(void) { 2228 extern CFTypeRef CFGetSomething(void); 2229 return CFAutorelease(CFGetSomething()); // expected-warning{{Object autoreleased too many times}} 2230} 2231 2232CFTypeRef createIncorrectlyAutoreleasedCFType(void) { 2233 extern CFTypeRef CFCreateSomething(void); 2234 return CFAutorelease(CFCreateSomething()); // expected-warning{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} 2235} 2236 2237void useAfterAutorelease(void) { 2238 extern CFTypeRef CFCreateSomething(void); 2239 CFTypeRef obj = CFCreateSomething(); 2240 CFAutorelease(obj); 2241 2242 extern void useCF(CFTypeRef); 2243 useCF(obj); // no-warning 2244} 2245 2246void useAfterRelease(void) { 2247 // Verify that the previous example would have warned with CFRelease. 2248 extern CFTypeRef CFCreateSomething(void); 2249 CFTypeRef obj = CFCreateSomething(); 2250 CFRelease(obj); 2251 2252 extern void useCF(CFTypeRef); 2253 useCF(obj); // expected-warning{{Reference-counted object is used after it is released}} 2254} 2255 2256void testAutoreleaseReturnsInput(void) { 2257 extern CFTypeRef CFCreateSomething(void); 2258 CFTypeRef obj = CFCreateSomething(); // expected-warning{{Potential leak of an object stored into 'second'}} 2259 CFTypeRef second = CFAutorelease(obj); 2260 CFRetain(second); 2261} 2262 2263CFTypeRef testAutoreleaseReturnsInputSilent(void) { 2264 extern CFTypeRef CFCreateSomething(void); 2265 CFTypeRef obj = CFCreateSomething(); 2266 CFTypeRef alias = CFAutorelease(obj); 2267 CFRetain(alias); 2268 CFRelease(obj); 2269 return obj; // no-warning 2270} 2271 2272void autoreleaseTypedObject(void) { 2273 CFArrayRef arr = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); 2274 CFAutorelease((CFTypeRef)arr); // no-warning 2275} 2276 2277void autoreleaseReturningTypedObject(void) { 2278 CFArrayRef arr = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{Potential leak of an object stored into 'alias'}} 2279 CFArrayRef alias = (CFArrayRef)CFAutorelease((CFTypeRef)arr); 2280 CFRetain(alias); 2281} 2282 2283CFArrayRef autoreleaseReturningTypedObjectSilent(void) { 2284 CFArrayRef arr = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); 2285 CFArrayRef alias = (CFArrayRef)CFAutorelease((CFTypeRef)arr); 2286 CFRetain(alias); 2287 CFRelease(arr); 2288 return alias; // no-warning 2289} 2290 2291void autoreleaseObjC(void) { 2292 id obj = [@1 retain]; 2293 CFAutorelease(obj); // no-warning 2294 2295 id anotherObj = @1; 2296 CFAutorelease(anotherObj); 2297} // expected-warning{{Object autoreleased too many times}} 2298 2299//===----------------------------------------------------------------------===// 2300// xpc_connection_set_finalizer_f 2301//===----------------------------------------------------------------------===// 2302typedef xpc_object_t xpc_connection_t; 2303typedef void (*xpc_finalizer_t)(void *value); 2304void xpc_connection_set_context(xpc_connection_t connection, void *ctx); 2305void xpc_connection_set_finalizer_f(xpc_connection_t connection, 2306 xpc_finalizer_t finalizer); 2307void releaseAfterXPC(void *context) { 2308 [(NSArray *)context release]; 2309} 2310 2311void rdar13783514(xpc_connection_t connection) { 2312 xpc_connection_set_context(connection, [[NSMutableArray alloc] init]); 2313 xpc_connection_set_finalizer_f(connection, releaseAfterXPC); 2314} // no-warning 2315 2316// Do not report leaks when object is cleaned up with __attribute__((cleanup ..)). 2317inline static void cleanupFunction(void *tp) { 2318 CFTypeRef x = *(CFTypeRef *)tp; 2319 if (x) { 2320 CFRelease(x); 2321 } 2322} 2323#define ADDCLEANUP __attribute__((cleanup(cleanupFunction))) 2324void foo(void) { 2325 ADDCLEANUP CFStringRef myString; 2326 myString = CFStringCreateWithCString(0, "hello world", kCFStringEncodingUTF8); 2327 ADDCLEANUP CFStringRef myString2 = 2328 CFStringCreateWithCString(0, "hello world", kCFStringEncodingUTF8); 2329} 2330 2331//===----------------------------------------------------------------------===// 2332// Handle NSNull 2333//===----------------------------------------------------------------------===// 2334 2335__attribute__((ns_returns_retained)) 2336id returnNSNull(void) { 2337 return [NSNull null]; // no-warning 2338} 2339 2340//===----------------------------------------------------------------------===// 2341// cf_returns_[not_]retained on parameters 2342//===----------------------------------------------------------------------===// 2343 2344void testCFReturnsNotRetained(void) { 2345 extern void getViaParam(CFTypeRef * CF_RETURNS_NOT_RETAINED outObj); 2346 CFTypeRef obj; 2347 getViaParam(&obj); 2348 CFRelease(obj); // // expected-warning {{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} 2349} 2350 2351void testCFReturnsNotRetainedAnnotated(void) { 2352 extern void getViaParam2(CFTypeRef * _Nonnull CF_RETURNS_NOT_RETAINED outObj); 2353 CFTypeRef obj; 2354 getViaParam2(&obj); 2355 CFRelease(obj); // // expected-warning {{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} 2356} 2357 2358void testCFReturnsRetained(void) { 2359 extern int copyViaParam(CFTypeRef * CF_RETURNS_RETAINED outObj); 2360 CFTypeRef obj; 2361 copyViaParam(&obj); 2362 CFRelease(obj); 2363 CFRelease(obj); // // FIXME-warning {{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} 2364} 2365 2366void testCFReturnsRetainedError(void) { 2367 extern int copyViaParam(CFTypeRef * CF_RETURNS_RETAINED outObj); 2368 CFTypeRef obj; 2369 if (copyViaParam(&obj) == -42) 2370 return; // no-warning 2371 CFRelease(obj); 2372} 2373