diff options
Diffstat (limited to 'test/Analysis/retain-release.m')
-rw-r--r-- | test/Analysis/retain-release.m | 130 |
1 files changed, 123 insertions, 7 deletions
diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m index 06c510e5dd3ef..ba492b7b19a7f 100644 --- a/test/Analysis/retain-release.m +++ b/test/Analysis/retain-release.m @@ -142,9 +142,13 @@ NSFastEnumerationState; @end @class NSString, NSDictionary; @interface NSValue : NSObject <NSCopying, NSCoding> - (void)getValue:(void *)value; -@end @interface NSNumber : NSValue - (char)charValue; +@end +@interface NSNumber : NSValue +- (char)charValue; - (id)initWithInt:(int)value; -@end @class NSString; ++ (NSNumber *)numberWithInt:(int)value; +@end +@class NSString; @interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration> - (NSUInteger)count; - (id)initWithObjects:(const id [])objects count:(NSUInteger)cnt; @@ -195,7 +199,7 @@ typedef struct IONotificationPort * IONotificationPortRef; typedef void (*IOServiceMatchingCallback)( void * refcon, io_iterator_t iterator ); io_service_t IOServiceGetMatchingService( mach_port_t masterPort, CFDictionaryRef matching ); kern_return_t IOServiceGetMatchingServices( mach_port_t masterPort, CFDictionaryRef matching, io_iterator_t * existing ); -kern_return_t IOServiceAddNotification( mach_port_t masterPort, const io_name_t notificationType, CFDictionaryRef matching, mach_port_t wakePort, uintptr_t reference, io_iterator_t * notification ) __attribute__((deprecated)); +kern_return_t IOServiceAddNotification( mach_port_t masterPort, const io_name_t notificationType, CFDictionaryRef matching, mach_port_t wakePort, uintptr_t reference, io_iterator_t * notification ) __attribute__((deprecated)); // expected-note {{'IOServiceAddNotification' declared here}} kern_return_t IOServiceAddMatchingNotification( IONotificationPortRef notifyPort, const io_name_t notificationType, CFDictionaryRef matching, IOServiceMatchingCallback callback, void * refCon, io_iterator_t * notification ); CFMutableDictionaryRef IOServiceMatching( const char * name ); CFMutableDictionaryRef IOServiceNameMatching( const char * name ); @@ -222,8 +226,10 @@ typedef struct CGLayer *CGLayerRef; @end @protocol NSValidatedUserInterfaceItem - (SEL)action; @end @protocol NSUserInterfaceValidations - (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)anItem; @end @class NSDate, NSDictionary, NSError, NSException, NSNotification; +@class NSTextField, NSPanel, NSArray, NSWindow, NSImage, NSButton, NSError; @interface NSApplication : NSResponder <NSUserInterfaceValidations> { } +- (void)beginSheet:(NSWindow *)sheet modalForWindow:(NSWindow *)docWindow modalDelegate:(id)modalDelegate didEndSelector:(SEL)didEndSelector contextInfo:(void *)contextInfo; @end enum { NSTerminateCancel = 0, NSTerminateNow = 1, NSTerminateLater = 2 }; typedef NSUInteger NSApplicationTerminateReply; @@ -231,7 +237,7 @@ typedef NSUInteger NSApplicationTerminateReply; @end @class NSAttributedString, NSEvent, NSFont, NSFormatter, NSImage, NSMenu, NSText, NSView, NSTextView; @interface NSCell : NSObject <NSCopying, NSCoding> { } -@end @class NSTextField, NSPanel, NSArray, NSWindow, NSImage, NSButton, NSError; +@end typedef struct { } CVTimeStamp; @@ -294,6 +300,9 @@ extern CGColorSpaceRef CGColorSpaceCreateDeviceRGB(void); + (id)array; @end +// This is how NSMakeCollectable is declared in the OS X 10.8 headers. +id NSMakeCollectable(CFTypeRef __attribute__((cf_consumed))) __attribute__((ns_returns_retained)); + //===----------------------------------------------------------------------===// // Test cases. @@ -747,7 +756,7 @@ typedef CFTypeRef OtherRef; @end //===----------------------------------------------------------------------===// -//<rdar://problem/6320065> false positive - init method returns an object +// <rdar://problem/6320065> false positive - init method returns an object // owned by caller //===----------------------------------------------------------------------===// @@ -1055,10 +1064,14 @@ typedef struct _opaque_pthread_t *__darwin_pthread_t; typedef struct _opaque_pthread_attr_t __darwin_pthread_attr_t; typedef __darwin_pthread_t pthread_t; typedef __darwin_pthread_attr_t pthread_attr_t; +typedef unsigned long __darwin_pthread_key_t; +typedef __darwin_pthread_key_t pthread_key_t; int pthread_create(pthread_t *, const pthread_attr_t *, void *(*)(void *), void *); +int pthread_setspecific(pthread_key_t key, const void *value); + void *rdar_7299394_start_routine(void *p) { [((id) p) release]; return 0; @@ -1072,6 +1085,16 @@ void rdar_7299394_positive(pthread_attr_t *attr, pthread_t *thread) { } //===----------------------------------------------------------------------===// +// <rdar://problem/11282706> false positive with not understanding thread +// local storage +//===----------------------------------------------------------------------===// + +void rdar11282706(pthread_key_t key) { + NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning + pthread_setspecific(key, (void*) number); +} + +//===----------------------------------------------------------------------===// // <rdar://problem/7283567> False leak associated with call to // CVPixelBufferCreateWithBytes () // @@ -1291,6 +1314,11 @@ void testattr2_b() { TestOwnershipAttr *x = [[TestOwnershipAttr alloc] pseudoInit]; // expected-warning{{leak}} } +void testattr2_b_11358224_self_assign_looses_the_leak() { + TestOwnershipAttr *x = [[TestOwnershipAttr alloc] pseudoInit];// expected-warning{{leak}} + x = x; +} + void testattr2_c() { TestOwnershipAttr *x = [[TestOwnershipAttr alloc] pseudoInit]; // no-warning [x release]; @@ -1427,8 +1455,7 @@ void test_blocks_1_indirect_release_via_call(void) { } void test_blocks_1_indirect_retain_via_call(void) { - // Eventually this should be reported as a leak. - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning + NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning {{leak}} ^(NSObject *o){ [o retain]; }(number); } @@ -1667,6 +1694,58 @@ void rdar_10824732() { } } +// Stop tracking objects passed to functions, which take callbacks as parameters. +// radar://10973977 +typedef int (*CloseCallback) (void *); +void ReaderForIO(CloseCallback ioclose, void *ioctx); +int IOClose(void *context); + +@protocol SInS <NSObject> +@end + +@interface radar10973977 : NSObject +- (id<SInS>)inputS; +- (void)reader; +@end + +@implementation radar10973977 +- (void)reader +{ + id<SInS> inputS = [[self inputS] retain]; + ReaderForIO(IOClose, inputS); +} +- (id<SInS>)inputS +{ + return 0; +} +@end + +// Object escapes through a selector callback: radar://11398514 +extern id NSApp; +@interface MySheetController +- (id<SInS>)inputS; +- (void)showDoSomethingSheetAction:(id)action; +- (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo; +@end + +@implementation MySheetController +- (id<SInS>)inputS { + return 0; +} +- (void)showDoSomethingSheetAction:(id)action { + id<SInS> inputS = [[self inputS] retain]; + [NSApp beginSheet:0 + modalForWindow:0 + modalDelegate:0 + didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) + contextInfo:(void *)inputS]; // no - warning +} +- (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo { + + id contextObject = (id)contextInfo; + [contextObject release]; +} +@end //===----------------------------------------------------------------------===// // Test returning allocated memory in a struct. // @@ -1739,3 +1818,40 @@ void test_objc_arrays() { } } +void test_objc_integer_literals() { + id value = [@1 retain]; // expected-warning {{leak}} + [value description]; +} + +void test_objc_boxed_expressions(int x, const char *y) { + id value = [@(x) retain]; // expected-warning {{leak}} + [value description]; + + value = [@(y) retain]; // expected-warning {{leak}} + [value description]; +} + +// Test NSLog doesn't escape tracked objects. +void rdar11400885(int y) +{ + @autoreleasepool { + NSString *printString; + if(y > 2) + printString = [[NSString alloc] init]; + else + printString = [[NSString alloc] init]; + NSLog(@"Once %@", printString); + [printString release]; + NSLog(@"Again: %@", printString); // expected-warning {{Reference-counted object is used after it is released}} + } +} + +id makeCollectableNonLeak() { + extern CFTypeRef CFCreateSomething(); + + CFTypeRef object = CFCreateSomething(); // +1 + CFRetain(object); // +2 + id objCObject = NSMakeCollectable(object); // +2 + [objCObject release]; // +1 + return [objCObject autorelease]; // +0 +} |