diff options
Diffstat (limited to 'test/ARCMT')
40 files changed, 7527 insertions, 36 deletions
diff --git a/test/ARCMT/Inputs/test1.m.in b/test/ARCMT/Inputs/test1.m.in index 8416a88..44a3c4c 100644 --- a/test/ARCMT/Inputs/test1.m.in +++ b/test/ARCMT/Inputs/test1.m.in @@ -4,3 +4,13 @@ void test1(id p) { [p release]; } + +@interface Test2 +@property (strong) id prop; +@end + +@implementation Test2 +-(id)init { + _prop = 0; +} +@end diff --git a/test/ARCMT/Inputs/test1.m.in.result b/test/ARCMT/Inputs/test1.m.in.result index f351fe6..1db9bf7 100644 --- a/test/ARCMT/Inputs/test1.m.in.result +++ b/test/ARCMT/Inputs/test1.m.in.result @@ -3,3 +3,13 @@ void test1(id p) { } + +@interface Test2 +@property (strong) id prop; +@end + +@implementation Test2 +-(id)init { + _prop = 0; +} +@end diff --git a/test/ARCMT/checking-in-arc.m b/test/ARCMT/checking-in-arc.m new file mode 100644 index 0000000..40d9b16 --- /dev/null +++ b/test/ARCMT/checking-in-arc.m @@ -0,0 +1,51 @@ +// RUN: %clang_cc1 -arcmt-check -fobjc-arc -fobjc-runtime=macosx-10.8.0 -triple x86_64-apple-darwin12 -fblocks -Werror %s +// DISABLE: mingw32 + +#if __has_feature(objc_arc) +#define NS_AUTOMATED_REFCOUNT_UNAVAILABLE __attribute__((unavailable("not available in automatic reference counting mode"))) +#else +#define NS_AUTOMATED_REFCOUNT_UNAVAILABLE +#endif + +typedef const void * CFTypeRef; +CFTypeRef CFBridgingRetain(id X); +id CFBridgingRelease(CFTypeRef); + +typedef int BOOL; +typedef unsigned NSUInteger; + +@protocol NSObject +- (id)retain NS_AUTOMATED_REFCOUNT_UNAVAILABLE; +- (NSUInteger)retainCount NS_AUTOMATED_REFCOUNT_UNAVAILABLE; +- (oneway void)release NS_AUTOMATED_REFCOUNT_UNAVAILABLE; +- (id)autorelease NS_AUTOMATED_REFCOUNT_UNAVAILABLE; +@end + +@interface NSObject <NSObject> {} +- (id)init; + ++ (id)new; ++ (id)alloc; +- (void)dealloc; + +- (void)finalize; + +- (id)copy; +- (id)mutableCopy; +@end + +typedef const struct __CFString * CFStringRef; +extern const CFStringRef kUTTypePlainText; +extern const CFStringRef kUTTypeRTF; +@class NSString; + +@interface Test : NSObject +@property (weak) NSString *weakProperty; +@end + +@implementation Test +@end + +#if ! __has_feature(objc_arc) +#error This file must be compiled with ARC (set -fobjc_arc flag on file) +#endif diff --git a/test/ARCMT/checking.m b/test/ARCMT/checking.m index b06f4a7..a550633 100644 --- a/test/ARCMT/checking.m +++ b/test/ARCMT/checking.m @@ -333,7 +333,9 @@ void rdar9504750(id p) { } @end -@interface Test10 : NSObject +@interface Test10 : NSObject { + CFStringRef cfstr; +} @property (retain) id prop; -(void)foo; @end @@ -342,3 +344,13 @@ void test(Test10 *x) { x.prop = ^{ [x foo]; }; // expected-warning {{likely to lead to a retain cycle}} \ // expected-note {{retained by the captured object}} } + +@implementation Test10 +-(void)foo { + ^{ + NSString *str = (NSString *)cfstr; // expected-error {{cast of C pointer type 'CFStringRef' (aka 'const struct __CFString *') to Objective-C pointer type 'NSString *' requires a bridged cast}} \ + // expected-note {{use __bridge to convert directly (no change in ownership)}} \ + // expected-note {{use CFBridgingRelease call to transfer ownership of a +1 'CFStringRef' (aka 'const struct __CFString *') into ARC}} + }; +} +@end diff --git a/test/ARCMT/driver-migrate.m b/test/ARCMT/driver-migrate.m index a912ad9..b1e419a 100644 --- a/test/ARCMT/driver-migrate.m +++ b/test/ARCMT/driver-migrate.m @@ -10,3 +10,6 @@ // LINK-NOT: {{ld(.exe)?"}} // LINK: {{touch(.exe)?"}} + +// RUN: %clang -### -ccc-arcmt-migrate /foo/bar -fsyntax-only -fno-objc-arc %s 2>&1 | FileCheck -check-prefix=CHECK-NOARC %s +// CHECK-NOARC-NOT: argument unused during compilation diff --git a/test/ARCMT/lit.local.cfg b/test/ARCMT/lit.local.cfg new file mode 100644 index 0000000..4b28d6d --- /dev/null +++ b/test/ARCMT/lit.local.cfg @@ -0,0 +1,2 @@ +if config.root.clang_arcmt == 0: + config.unsupported = True diff --git a/test/ARCMT/objcmt-arc-cf-annotations.m b/test/ARCMT/objcmt-arc-cf-annotations.m new file mode 100644 index 0000000..9772825 --- /dev/null +++ b/test/ARCMT/objcmt-arc-cf-annotations.m @@ -0,0 +1,2047 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fblocks -objcmt-migrate-annotation -objcmt-migrate-instancetype -objcmt-migrate-readwrite-property -mt-migrate-directory %t %s -x objective-c -triple x86_64-apple-darwin11 +// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result +// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s.result + +#ifndef CF_IMPLICIT_BRIDGING_ENABLED +#if __has_feature(arc_cf_code_audited) +#define CF_IMPLICIT_BRIDGING_ENABLED _Pragma("clang arc_cf_code_audited begin") +#else +#define CF_IMPLICIT_BRIDGING_ENABLED +#endif +#endif + +#ifndef CF_IMPLICIT_BRIDGING_DISABLED +#if __has_feature(arc_cf_code_audited) +#define CF_IMPLICIT_BRIDGING_DISABLED _Pragma("clang arc_cf_code_audited end") +#else +#define CF_IMPLICIT_BRIDGING_DISABLED +#endif +#endif + +#if __has_feature(attribute_ns_returns_retained) +#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained)) +#endif +#if __has_feature(attribute_cf_returns_retained) +#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained)) +#endif +#if __has_feature(attribute_ns_returns_not_retained) +#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained)) +#endif +#if __has_feature(attribute_cf_returns_not_retained) +#define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained)) +#endif +#if __has_feature(attribute_ns_consumes_self) +#define NS_CONSUMES_SELF __attribute__((ns_consumes_self)) +#endif +#if __has_feature(attribute_ns_consumed) +#define NS_CONSUMED __attribute__((ns_consumed)) +#endif +#if __has_feature(attribute_cf_consumed) +#define CF_CONSUMED __attribute__((cf_consumed)) +#endif +#if __has_attribute(ns_returns_autoreleased) +#define NS_RETURNS_AUTORELEASED __attribute__((ns_returns_autoreleased)) +#endif + +//===----------------------------------------------------------------------===// +// The following code is reduced using delta-debugging from Mac OS X headers: +// +// #include <Cocoa/Cocoa.h> +// #include <CoreFoundation/CoreFoundation.h> +// #include <DiskArbitration/DiskArbitration.h> +// #include <QuartzCore/QuartzCore.h> +// #include <Quartz/Quartz.h> +// #include <IOKit/IOKitLib.h> +// +// It includes the basic definitions for the test cases below. +//===----------------------------------------------------------------------===// + +typedef unsigned int __darwin_natural_t; +typedef unsigned long uintptr_t; +typedef unsigned int uint32_t; +typedef unsigned long long uint64_t; +typedef unsigned int UInt32; +typedef signed long CFIndex; +typedef CFIndex CFByteOrder; +typedef struct { + CFIndex location; + CFIndex length; +} CFRange; +static __inline__ __attribute__((always_inline)) CFRange CFRangeMake(CFIndex loc, CFIndex len) { + CFRange range; + range.location = loc; + range.length = len; + return range; +} +typedef const void * CFTypeRef; +typedef const struct __CFString * CFStringRef; +typedef const struct __CFAllocator * CFAllocatorRef; +extern const CFAllocatorRef kCFAllocatorDefault; +extern CFTypeRef CFRetain(CFTypeRef cf); +extern void CFRelease(CFTypeRef cf); +extern CFTypeRef CFMakeCollectable(CFTypeRef cf); +typedef struct { +} +CFArrayCallBacks; +extern const CFArrayCallBacks kCFTypeArrayCallBacks; +typedef const struct __CFArray * CFArrayRef; +typedef struct __CFArray * CFMutableArrayRef; +extern CFMutableArrayRef CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFArrayCallBacks *callBacks); +extern const void *CFArrayGetValueAtIndex(CFArrayRef theArray, CFIndex idx); +extern void CFArrayAppendValue(CFMutableArrayRef theArray, const void *value); +typedef struct { +} +CFDictionaryKeyCallBacks; +extern const CFDictionaryKeyCallBacks kCFTypeDictionaryKeyCallBacks; +typedef struct { +} +CFDictionaryValueCallBacks; +extern const CFDictionaryValueCallBacks kCFTypeDictionaryValueCallBacks; +typedef const struct __CFDictionary * CFDictionaryRef; +typedef struct __CFDictionary * CFMutableDictionaryRef; +extern CFMutableDictionaryRef CFDictionaryCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFDictionaryKeyCallBacks *keyCallBacks, const CFDictionaryValueCallBacks *valueCallBacks); +typedef UInt32 CFStringEncoding; +enum { +kCFStringEncodingMacRoman = 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 }; +extern CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding); +typedef double CFTimeInterval; +typedef CFTimeInterval CFAbsoluteTime; +extern CFAbsoluteTime CFAbsoluteTimeGetCurrent(void); +typedef const struct __CFDate * CFDateRef; +extern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at); +extern CFAbsoluteTime CFDateGetAbsoluteTime(CFDateRef theDate); +typedef __darwin_natural_t natural_t; +typedef natural_t mach_port_name_t; +typedef mach_port_name_t mach_port_t; +typedef int kern_return_t; +typedef kern_return_t mach_error_t; +enum { +kCFNumberSInt8Type = 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 }; +typedef CFIndex CFNumberType; +typedef const struct __CFNumber * CFNumberRef; +extern CFNumberRef CFNumberCreate(CFAllocatorRef allocator, CFNumberType theType, const void *valuePtr); +typedef const struct __CFAttributedString *CFAttributedStringRef; +typedef struct __CFAttributedString *CFMutableAttributedStringRef; +extern CFAttributedStringRef CFAttributedStringCreate(CFAllocatorRef alloc, CFStringRef str, CFDictionaryRef attributes) ; +extern CFMutableAttributedStringRef CFAttributedStringCreateMutableCopy(CFAllocatorRef alloc, CFIndex maxLength, CFAttributedStringRef aStr) ; +extern void CFAttributedStringSetAttribute(CFMutableAttributedStringRef aStr, CFRange range, CFStringRef attrName, CFTypeRef value) ; +typedef signed char BOOL; +typedef unsigned long NSUInteger; +@class NSString, Protocol; +extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2))); +typedef struct _NSZone NSZone; +@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; +@protocol NSObject +- (BOOL)isEqual:(id)object; +- (id)retain; +- (oneway void)release; +- (id)autorelease; +- (NSString *)description; +- (id)init; +@end +@protocol NSCopying +- (id)copyWithZone:(NSZone *)zone; +@end +@protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; +@end +@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; +@end +@interface NSObject <NSObject> {} ++ (id)allocWithZone:(NSZone *)zone; ++ (id)alloc; ++ (id)new; +- (void)dealloc; +@end +@interface NSObject (NSCoderMethods) +- (id)awakeAfterUsingCoder:(NSCoder *)aDecoder; +@end +extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone); +typedef struct { +} +NSFastEnumerationState; +@protocol NSFastEnumeration +- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len; +@end +@class NSString, NSDictionary; +@interface NSValue : NSObject <NSCopying, NSCoding> - (void)getValue:(void *)value; +@end +@interface NSNumber : NSValue +- (char)charValue; +- (id)initWithInt:(int)value; ++ (NSNumber *)numberWithInt:(int)value; +@end +@class NSString; +@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration> +- (NSUInteger)count; +- (id)initWithObjects:(const id [])objects count:(NSUInteger)cnt; ++ (id)arrayWithObject:(id)anObject; ++ (id)arrayWithObjects:(const id [])objects count:(NSUInteger)cnt; ++ (id)arrayWithObjects:(id)firstObj, ... __attribute__((sentinel(0,1))); +- (id)initWithObjects:(id)firstObj, ... __attribute__((sentinel(0,1))); +- (id)initWithArray:(NSArray *)array; +@end @interface NSArray (NSArrayCreation) + (id)array; +@end @interface NSAutoreleasePool : NSObject { +} +- (void)drain; +@end extern NSString * const NSBundleDidLoadNotification; +typedef double NSTimeInterval; +@interface NSDate : NSObject <NSCopying, NSCoding> - (NSTimeInterval)timeIntervalSinceReferenceDate; +@end typedef unsigned short unichar; +@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding> +- (NSUInteger)length; +- (NSString *)stringByAppendingString:(NSString *)aString; +- ( const char *)UTF8String; +- (id)initWithUTF8String:(const char *)nullTerminatedCString; ++ (id)stringWithUTF8String:(const char *)nullTerminatedCString; +@end @class NSString, NSURL, NSError; +@interface NSData : NSObject <NSCopying, NSMutableCopying, NSCoding> - (NSUInteger)length; ++ (id)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length; ++ (id)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length freeWhenDone:(BOOL)b; +@end @class NSLocale, NSDate, NSCalendar, NSTimeZone, NSError, NSArray, NSMutableDictionary; +@interface NSDictionary : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration> +- (NSUInteger)count; ++ (id)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; ++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id <NSCopying> [])keys count:(NSUInteger)cnt; +@end +@interface NSMutableDictionary : NSDictionary - (void)removeObjectForKey:(id)aKey; +- (void)setObject:(id)anObject forKey:(id)aKey; +@end @interface NSMutableDictionary (NSMutableDictionaryCreation) + (id)dictionaryWithCapacity:(NSUInteger)numItems; +@end typedef double CGFloat; +struct CGSize { +}; +typedef struct CGSize CGSize; +struct CGRect { +}; +typedef struct CGRect CGRect; +typedef mach_port_t io_object_t; +typedef char io_name_t[128]; +typedef io_object_t io_iterator_t; +typedef io_object_t io_service_t; +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)); // 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 ); +CFMutableDictionaryRef IOBSDNameMatching( mach_port_t masterPort, uint32_t options, const char * bsdName ); +CFMutableDictionaryRef IOOpenFirmwarePathMatching( mach_port_t masterPort, uint32_t options, const char * path ); +CFMutableDictionaryRef IORegistryEntryIDMatching( uint64_t entryID ); +typedef struct __DASession * DASessionRef; +extern DASessionRef DASessionCreate( CFAllocatorRef allocator ); +typedef struct __DADisk * DADiskRef; +extern DADiskRef DADiskCreateFromBSDName( CFAllocatorRef allocator, DASessionRef session, const char * name ); +extern DADiskRef DADiskCreateFromIOMedia( CFAllocatorRef allocator, DASessionRef session, io_service_t media ); +extern CFDictionaryRef DADiskCopyDescription( DADiskRef disk ); +extern DADiskRef DADiskCopyWholeDisk( DADiskRef disk ); +@interface NSTask : NSObject - (id)init; +@end typedef struct CGColorSpace *CGColorSpaceRef; +typedef struct CGImage *CGImageRef; +typedef struct CGLayer *CGLayerRef; +@interface NSResponder : NSObject <NSCoding> { +} +@end @protocol NSAnimatablePropertyContainer - (id)animator; +@end extern NSString *NSAnimationTriggerOrderIn ; +@interface NSView : NSResponder <NSAnimatablePropertyContainer> { +} +@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; +@protocol NSApplicationDelegate <NSObject> @optional - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender; +@end @class NSAttributedString, NSEvent, NSFont, NSFormatter, NSImage, NSMenu, NSText, NSView, NSTextView; +@interface NSCell : NSObject <NSCopying, NSCoding> { +} +@end +typedef struct { +} +CVTimeStamp; +@interface CIImage : NSObject <NSCoding, NSCopying> { +} +typedef int CIFormat; +@end enum { +kDAReturnSuccess = 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 }; +typedef mach_error_t DAReturn; +typedef const struct __DADissenter * DADissenterRef; +extern DADissenterRef DADissenterCreate( CFAllocatorRef allocator, DAReturn status, CFStringRef string ); +@interface CIContext: NSObject { +} +- (CGImageRef)createCGImage:(CIImage *)im fromRect:(CGRect)r; +- (CGImageRef)createCGImage:(CIImage *)im fromRect:(CGRect)r format:(CIFormat)f colorSpace:(CGColorSpaceRef)cs; +- (CGLayerRef)createCGLayerWithSize:(CGSize)size info:(CFDictionaryRef)d; +@end extern NSString* const QCRendererEventKey; +@protocol QCCompositionRenderer - (NSDictionary*) attributes; +@end @interface QCRenderer : NSObject <QCCompositionRenderer> { +} +- (id) createSnapshotImageOfType:(NSString*)type; +@end extern NSString* const QCViewDidStartRenderingNotification; +@interface QCView : NSView <QCCompositionRenderer> { +} +- (id) createSnapshotImageOfType:(NSString*)type; +@end enum { +ICEXIFOrientation1 = 1, ICEXIFOrientation2 = 2, ICEXIFOrientation3 = 3, ICEXIFOrientation4 = 4, ICEXIFOrientation5 = 5, ICEXIFOrientation6 = 6, ICEXIFOrientation7 = 7, ICEXIFOrientation8 = 8, }; +@class ICDevice; +@protocol ICDeviceDelegate <NSObject> @required - (void)didRemoveDevice:(ICDevice*)device; +@end extern NSString *const ICScannerStatusWarmingUp; +@class ICScannerDevice; +@protocol ICScannerDeviceDelegate <ICDeviceDelegate> @optional - (void)scannerDeviceDidBecomeAvailable:(ICScannerDevice*)scanner; +@end + +typedef long unsigned int __darwin_size_t; +typedef __darwin_size_t size_t; +typedef unsigned long CFTypeID; +struct CGPoint { + CGFloat x; + CGFloat y; +}; +typedef struct CGPoint CGPoint; +typedef struct CGGradient *CGGradientRef; +typedef uint32_t CGGradientDrawingOptions; +extern CFTypeID CGGradientGetTypeID(void); +extern CGGradientRef CGGradientCreateWithColorComponents(CGColorSpaceRef + space, const CGFloat components[], const CGFloat locations[], size_t count); +extern CGGradientRef CGGradientCreateWithColors(CGColorSpaceRef space, + CFArrayRef colors, const CGFloat locations[]); +extern CGGradientRef CGGradientRetain(CGGradientRef gradient); +extern void CGGradientRelease(CGGradientRef gradient); +typedef struct CGContext *CGContextRef; +extern void CGContextDrawLinearGradient(CGContextRef context, + CGGradientRef gradient, CGPoint startPoint, CGPoint endPoint, + CGGradientDrawingOptions options); +extern CGColorSpaceRef CGColorSpaceCreateDeviceRGB(void); + +@interface NSMutableArray : NSObject +- (void)addObject:(id)object; ++ (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)); + +typedef const struct __CFUUID * CFUUIDRef; + +extern +void *CFPlugInInstanceCreate(CFAllocatorRef allocator, CFUUIDRef factoryUUID, CFUUIDRef typeUUID); + +//===----------------------------------------------------------------------===// +// Test cases. +//===----------------------------------------------------------------------===// + +CFAbsoluteTime f1() { + CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); + CFDateRef date = CFDateCreate(0, t); + CFRetain(date); + CFRelease(date); + CFDateGetAbsoluteTime(date); // no-warning + CFRelease(date); + t = CFDateGetAbsoluteTime(date); // expected-warning{{Reference-counted object is used after it is released}} + return t; +} + +CFAbsoluteTime f2() { + CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); + CFDateRef date = CFDateCreate(0, t); + [((NSDate*) date) retain]; + CFRelease(date); + CFDateGetAbsoluteTime(date); // no-warning + [((NSDate*) date) release]; + t = CFDateGetAbsoluteTime(date); // expected-warning{{Reference-counted object is used after it is released}} + return t; +} + + +NSDate* global_x; + +// Test to see if we supresss an error when we store the pointer +// to a global. + +CFAbsoluteTime f3() { + CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); + CFDateRef date = CFDateCreate(0, t); + [((NSDate*) date) retain]; + CFRelease(date); + CFDateGetAbsoluteTime(date); // no-warning + global_x = (NSDate*) date; + [((NSDate*) date) release]; + t = CFDateGetAbsoluteTime(date); // no-warning + return t; +} + +//--------------------------------------------------------------------------- +// Test case 'f4' differs for region store and basic store. See +// retain-release-region-store.m and retain-release-basic-store.m. +//--------------------------------------------------------------------------- + +// Test a leak. + +CFAbsoluteTime f5(int x) { + CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); + CFDateRef date = CFDateCreate(0, t); // expected-warning{{leak}} + + if (x) + CFRelease(date); + + return t; +} + +// Test a leak involving the return. + +CFDateRef f6(int x) { + CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); // expected-warning{{leak}} + CFRetain(date); + return date; +} + +// Test a leak involving an overwrite. + +CFDateRef f7() { + CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); //expected-warning{{leak}} + CFRetain(date); + date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); // expected-warning {{leak}} + return date; +} + +// Generalization of Create rule. MyDateCreate returns a CFXXXTypeRef, and +// has the word create. +CFDateRef MyDateCreate(); + +CFDateRef f8() { + CFDateRef date = MyDateCreate(); // expected-warning{{leak}} + CFRetain(date); + return date; +} + +__attribute__((cf_returns_retained)) CFDateRef f9() { + CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); // no-warning + int *p = 0; + // When allocations fail, CFDateCreate can return null. + if (!date) *p = 1; // expected-warning{{null}} + return date; +} + +// Handle DiskArbitration API: +// +// http://developer.apple.com/DOCUMENTATION/DARWIN/Reference/DiscArbitrationFramework/ +// +void f10(io_service_t media, DADiskRef d, CFStringRef s) { + DADiskRef disk = DADiskCreateFromBSDName(kCFAllocatorDefault, 0, "hello"); // expected-warning{{leak}} + if (disk) NSLog(@"ok"); + + disk = DADiskCreateFromIOMedia(kCFAllocatorDefault, 0, media); // expected-warning{{leak}} + if (disk) NSLog(@"ok"); + + CFDictionaryRef dict = DADiskCopyDescription(d); // expected-warning{{leak}} + if (dict) NSLog(@"ok"); + + disk = DADiskCopyWholeDisk(d); // expected-warning{{leak}} + if (disk) NSLog(@"ok"); + + DADissenterRef dissenter = DADissenterCreate(kCFAllocatorDefault, // expected-warning{{leak}} + kDAReturnSuccess, s); + if (dissenter) NSLog(@"ok"); + + DASessionRef session = DASessionCreate(kCFAllocatorDefault); // expected-warning{{leak}} + if (session) NSLog(@"ok"); +} + +// Test retain/release checker with CFString and CFMutableArray. +void f11() { + // Create the array. + CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); + + // Create a string. + CFStringRef s1 = CFStringCreateWithCString(0, "hello world", + kCFStringEncodingUTF8); + + // Add the string to the array. + CFArrayAppendValue(A, s1); + + // Decrement the reference count. + CFRelease(s1); // no-warning + + // Get the string. We don't own it. + s1 = (CFStringRef) CFArrayGetValueAtIndex(A, 0); + + // Release the array. + CFRelease(A); // no-warning + + // Release the string. This is a bug. + CFRelease(s1); // expected-warning{{Incorrect decrement of the reference count}} +} + +// PR 3337: Handle functions declared using typedefs. +typedef CFTypeRef CREATEFUN(); +CFTypeRef MyCreateFun(); + +void f12() { + CFTypeRef o = MyCreateFun(); // expected-warning {{leak}} +} + +void f13_autorelease() { + CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning + [(id) A autorelease]; // no-warning +} + +void f13_autorelease_b() { + CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); + [(id) A autorelease]; + [(id) A autorelease]; +} // expected-warning{{Object autoreleased too many times}} + +CFMutableArrayRef f13_autorelease_c() { + CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); + [(id) A autorelease]; + [(id) A autorelease]; + return A; // expected-warning{{Object autoreleased too many times}} +} + +CFMutableArrayRef f13_autorelease_d() { + CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); + [(id) A autorelease]; + [(id) A autorelease]; + CFMutableArrayRef B = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{Object autoreleased too many times}} + CFRelease(B); // no-warning + while (1) {} +} + + +// This case exercises the logic where the leak site is the same as the allocation site. +void f14_leakimmediately() { + CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{leak}} +} + +// Test that we track an allocated object beyond the point where the *name* +// of the variable storing the reference is no longer live. +void f15() { + // Create the array. + CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); + CFMutableArrayRef *B = &A; + // At this point, the name 'A' is no longer live. + CFRelease(*B); // no-warning +} + +// Test when we pass NULL to CFRetain/CFRelease/CFMakeCollectable. +void f16(int x, CFTypeRef p) { + if (p) + return; + + if (x > 0) { + CFRelease(p); // expected-warning{{Null pointer argument in call to CFRelease}} + } + else if (x < 0) { + CFRetain(p); // expected-warning{{Null pointer argument in call to CFRetain}} + } + else { + CFMakeCollectable(p); // expected-warning{{Null pointer argument in call to CFMakeCollectable}} + } +} + +// Test that an object is non-null after being CFRetained/CFReleased. +void f17(int x, CFTypeRef p) { + if (x > 0) { + CFRelease(p); + if (!p) + CFRelease(0); // no-warning + } + else if (x < 0) { + CFRetain(p); + if (!p) + CFRetain(0); // no-warning + } + else { + CFMakeCollectable(p); + if (!p) + CFMakeCollectable(0); // no-warning + } +} + +// Test basic tracking of ivars associated with 'self'. For the retain/release +// checker we currently do not want to flag leaks associated with stores +// of tracked objects to ivars. +@interface SelfIvarTest : NSObject { + id myObj; +} +- (void)test_self_tracking; +@end + +@implementation SelfIvarTest +- (void)test_self_tracking { + myObj = (id) CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning +} +@end + +// Test return of non-owned objects in contexts where an owned object +// is expected. +@interface TestReturnNotOwnedWhenExpectedOwned +- (NSString*)newString; +@end + +@implementation TestReturnNotOwnedWhenExpectedOwned +- (NSString*)newString { + NSString *s = [NSString stringWithUTF8String:"hello"]; + return s; // expected-warning{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} +} +@end + +// <rdar://problem/6659160> +int isFoo(char c); + +static void rdar_6659160(char *inkind, char *inname) +{ + // We currently expect that [NSObject alloc] cannot fail. This + // will be a toggled flag in the future. It can indeed return null, but + // Cocoa programmers generally aren't expected to reason about out-of-memory + // conditions. + NSString *kind = [[NSString alloc] initWithUTF8String:inkind]; // expected-warning{{leak}} + + // We do allow stringWithUTF8String to fail. This isn't really correct, as + // far as returning 0. In most error conditions it will throw an exception. + // If allocation fails it could return 0, but again this + // isn't expected. + NSString *name = [NSString stringWithUTF8String:inname]; + if(!name) + return; + + const char *kindC = 0; + const char *nameC = 0; + + // In both cases, we cannot reach a point down below where we + // dereference kindC or nameC with either being null. This is because + // we assume that [NSObject alloc] doesn't fail and that we have the guard + // up above. + + if(kind) + kindC = [kind UTF8String]; + if(name) + nameC = [name UTF8String]; + if(!isFoo(kindC[0])) // expected-warning{{null}} + return; + if(!isFoo(nameC[0])) // no-warning + return; + + [kind release]; + [name release]; // expected-warning{{Incorrect decrement of the reference count}} +} + +// PR 3677 - 'allocWithZone' should be treated as following the Cocoa naming +// conventions with respect to 'return'ing ownership. +@interface PR3677: NSObject @end +@implementation PR3677 ++ (id)allocWithZone:(NSZone *)inZone { + return [super allocWithZone:inZone]; // no-warning +} +@end + +// PR 3820 - Reason about calls to -dealloc +void pr3820_DeallocInsteadOfRelease(void) +{ + id foo = [[NSString alloc] init]; // no-warning + [foo dealloc]; + // foo is not leaked, since it has been deallocated. +} + +void pr3820_ReleaseAfterDealloc(void) +{ + id foo = [[NSString alloc] init]; + [foo dealloc]; + [foo release]; // expected-warning{{used after it is release}} + // NSInternalInconsistencyException: message sent to deallocated object +} + +void pr3820_DeallocAfterRelease(void) +{ + NSLog(@"\n\n[%s]", __FUNCTION__); + id foo = [[NSString alloc] init]; + [foo release]; + [foo dealloc]; // expected-warning{{used after it is released}} + // message sent to released object +} + +// From <rdar://problem/6704930>. The problem here is that 'length' binds to +// '($0 - 1)' after '--length', but SimpleConstraintManager doesn't know how to +// reason about '($0 - 1) > constant'. As a temporary hack, we drop the value +// of '($0 - 1)' and conjure a new symbol. +void rdar6704930(unsigned char *s, unsigned int length) { + NSString* name = 0; + if (s != 0) { + if (length > 0) { + while (length > 0) { + if (*s == ':') { + ++s; + --length; + name = [[NSString alloc] init]; // no-warning + break; + } + ++s; + --length; + } + if ((length == 0) && (name != 0)) { + [name release]; + name = 0; + } + if (length == 0) { // no ':' found -> use it all as name + name = [[NSString alloc] init]; // no-warning + } + } + } + + if (name != 0) { + [name release]; + } +} + +//===----------------------------------------------------------------------===// +// <rdar://problem/6833332> +// One build of the analyzer accidentally stopped tracking the allocated +// object after the 'retain'. +//===----------------------------------------------------------------------===// + +@interface rdar_6833332 : NSObject <NSApplicationDelegate> { + NSWindow *window; +} +@property (nonatomic, retain) NSWindow *window; +@end + +@implementation rdar_6833332 +@synthesize window; +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + NSMutableDictionary *dict = [[NSMutableDictionary dictionaryWithCapacity:4] retain]; // expected-warning{{leak}} + + [dict setObject:@"foo" forKey:@"bar"]; + + NSLog(@"%@", dict); +} +- (void)dealloc { + [window release]; + [super dealloc]; +} + +- (void)radar10102244 { + NSMutableDictionary *dict = [[NSMutableDictionary dictionaryWithCapacity:4] retain]; // expected-warning{{leak}} + if (window) + NSLog(@"%@", window); +} +@end + +//===----------------------------------------------------------------------===// +// <rdar://problem/6257780> clang checker fails to catch use-after-release +//===----------------------------------------------------------------------===// + +int rdar_6257780_Case1() { + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + NSArray *array = [NSArray array]; + [array release]; // expected-warning{{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} + [pool drain]; + return 0; +} + +//===----------------------------------------------------------------------===// +// <rdar://problem/10640253> Analyzer is confused about NSAutoreleasePool -allocWithZone:. +//===----------------------------------------------------------------------===// + +void rdar_10640253_autorelease_allocWithZone() { + NSAutoreleasePool *pool = [[NSAutoreleasePool allocWithZone:(NSZone*)0] init]; + (void) pool; +} + +//===----------------------------------------------------------------------===// +// <rdar://problem/6866843> Checker should understand new/setObject:/release constructs +//===----------------------------------------------------------------------===// + +void rdar_6866843() { + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + NSMutableDictionary* dictionary = [[NSMutableDictionary alloc] init]; + NSArray* array = [[NSArray alloc] init]; + [dictionary setObject:array forKey:@"key"]; + [array release]; + // Using 'array' here should be fine + NSLog(@"array = %@\n", array); // no-warning + // Now the array is released + [dictionary release]; + [pool drain]; +} + + +//===----------------------------------------------------------------------===// +// <rdar://problem/6877235> Classes typedef-ed to CF objects should get the same treatment as CF objects +//===----------------------------------------------------------------------===// + +typedef CFTypeRef OtherRef; + +@interface RDar6877235 : NSObject {} +- (CFTypeRef)_copyCFTypeRef; +- (OtherRef)_copyOtherRef; +@end + +@implementation RDar6877235 +- (CFTypeRef)_copyCFTypeRef { + return [[NSString alloc] init]; // no-warning +} +- (OtherRef)_copyOtherRef { + return [[NSString alloc] init]; // no-warning +} +@end + +//===----------------------------------------------------------------------===// +// <rdar://problem/6320065> false positive - init method returns an object +// owned by caller +//===----------------------------------------------------------------------===// + +@interface RDar6320065 : NSObject { + NSString *_foo; +} +- (id)initReturningNewClass; +- (id)_initReturningNewClassBad; +- (id)initReturningNewClassBad2; +@end + +@interface RDar6320065Subclass : RDar6320065 +@end + +@implementation RDar6320065 +- (id)initReturningNewClass { + [self release]; + self = [[RDar6320065Subclass alloc] init]; // no-warning + return self; +} +- (id)_initReturningNewClassBad { + [self release]; + [[RDar6320065Subclass alloc] init]; // expected-warning {{leak}} + return self; +} +- (id)initReturningNewClassBad2 { + [self release]; + self = [[RDar6320065Subclass alloc] init]; + return [self autorelease]; // expected-warning{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} +} + +@end + +@implementation RDar6320065Subclass +@end + +int RDar6320065_test() { + RDar6320065 *test = [[RDar6320065 alloc] init]; // no-warning + [test release]; + return 0; +} + +//===----------------------------------------------------------------------===// +// <rdar://problem/7129086> -awakeAfterUsingCoder: returns an owned object +// and claims the receiver +//===----------------------------------------------------------------------===// + +@interface RDar7129086 : NSObject {} @end +@implementation RDar7129086 +- (id)awakeAfterUsingCoder:(NSCoder *)aDecoder { + [self release]; // no-warning + return [NSString alloc]; // no-warning +} +@end + +//===----------------------------------------------------------------------===// +// <rdar://problem/6859457> [NSData dataWithBytesNoCopy] does not return a +// retained object +//===----------------------------------------------------------------------===// + +@interface RDar6859457 : NSObject {} +- (NSString*) NoCopyString; +- (NSString*) noCopyString; +@end + +@implementation RDar6859457 +- (NSString*) NoCopyString { return [[NSString alloc] init]; } // expected-warning{{leak}} +- (NSString*) noCopyString { return [[NSString alloc] init]; } // expected-warning{{leak}} +@end + +void test_RDar6859457(RDar6859457 *x, void *bytes, NSUInteger dataLength) { + [x NoCopyString]; // expected-warning{{leak}} + [x noCopyString]; // expected-warning{{leak}} + [NSData dataWithBytesNoCopy:bytes length:dataLength]; // no-warning + [NSData dataWithBytesNoCopy:bytes length:dataLength freeWhenDone:1]; // no-warning +} + +//===----------------------------------------------------------------------===// +// PR 4230 - an autorelease pool is not necessarily leaked during a premature +// return +//===----------------------------------------------------------------------===// + +static void PR4230(void) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // no-warning + NSString *object = [[[NSString alloc] init] autorelease]; // no-warning + return; +} + +static void PR4230_new(void) +{ + NSAutoreleasePool *pool = [NSAutoreleasePool new]; // no-warning + NSString *object = [[[NSString alloc] init] autorelease]; // no-warning + return; +} + +//===----------------------------------------------------------------------===// +// Method name that has a null IdentifierInfo* for its first selector slot. +// This test just makes sure that we handle it. +//===----------------------------------------------------------------------===// + +@interface TestNullIdentifier +@end + +@implementation TestNullIdentifier ++ (id):(int)x, ... { + return [[NSString alloc] init]; // expected-warning{{leak}} +} +@end + +//===----------------------------------------------------------------------===// +// <rdar://problem/6893565> don't flag leaks for return types that cannot be +// determined to be CF types +//===----------------------------------------------------------------------===// + +// We don't know if 'struct s6893565' represents a Core Foundation type, so +// we shouldn't emit an error here. +typedef struct s6893565* TD6893565; + +@interface RDar6893565 {} +-(TD6893565)newThing; +@end + +@implementation RDar6893565 +-(TD6893565)newThing { + return (TD6893565) [[NSString alloc] init]; // no-warning +} +@end + +//===----------------------------------------------------------------------===// +// <rdar://problem/6902710> clang: false positives w/QC and CoreImage methods +//===----------------------------------------------------------------------===// + +void rdar6902710(QCView *view, QCRenderer *renderer, CIContext *context, + NSString *str, CIImage *img, CGRect rect, + CIFormat form, CGColorSpaceRef cs) { + [view createSnapshotImageOfType:str]; // expected-warning{{leak}} + [renderer createSnapshotImageOfType:str]; // expected-warning{{leak}} + [context createCGImage:img fromRect:rect]; // expected-warning{{leak}} + [context createCGImage:img fromRect:rect format:form colorSpace:cs]; // expected-warning{{leak}} +} + +//===----------------------------------------------------------------------===// +// <rdar://problem/6945561> -[CIContext createCGLayerWithSize:info:] +// misinterpreted by clang scan-build +//===----------------------------------------------------------------------===// + +void rdar6945561(CIContext *context, CGSize size, CFDictionaryRef d) { + [context createCGLayerWithSize:size info:d]; // expected-warning{{leak}} +} + +//===----------------------------------------------------------------------===// +// <rdar://problem/6961230> add knowledge of IOKit functions to retain/release +// checker +//===----------------------------------------------------------------------===// + +void IOBSDNameMatching_wrapper(mach_port_t masterPort, uint32_t options, const char * bsdName) { + IOBSDNameMatching(masterPort, options, bsdName); // expected-warning{{leak}} +} + +void IOServiceMatching_wrapper(const char * name) { + IOServiceMatching(name); // expected-warning{{leak}} +} + +void IOServiceNameMatching_wrapper(const char * name) { + IOServiceNameMatching(name); // expected-warning{{leak}} +} + +CF_RETURNS_RETAINED CFDictionaryRef CreateDict(); + +void IOServiceAddNotification_wrapper(mach_port_t masterPort, const io_name_t notificationType, + mach_port_t wakePort, uintptr_t reference, io_iterator_t * notification ) { + + CFDictionaryRef matching = CreateDict(); + CFRelease(matching); + IOServiceAddNotification(masterPort, notificationType, matching, // expected-warning{{used after it is released}} expected-warning{{deprecated}} + wakePort, reference, notification); +} + +void IORegistryEntryIDMatching_wrapper(uint64_t entryID ) { + IORegistryEntryIDMatching(entryID); // expected-warning{{leak}} +} + +void IOOpenFirmwarePathMatching_wrapper(mach_port_t masterPort, uint32_t options, + const char * path) { + IOOpenFirmwarePathMatching(masterPort, options, path); // expected-warning{{leak}} +} + +void IOServiceGetMatchingService_wrapper(mach_port_t masterPort) { + CFDictionaryRef matching = CreateDict(); + IOServiceGetMatchingService(masterPort, matching); + CFRelease(matching); // expected-warning{{used after it is released}} +} + +void IOServiceGetMatchingServices_wrapper(mach_port_t masterPort, io_iterator_t *existing) { + CFDictionaryRef matching = CreateDict(); + IOServiceGetMatchingServices(masterPort, matching, existing); + CFRelease(matching); // expected-warning{{used after it is released}} +} + +void IOServiceAddMatchingNotification_wrapper(IONotificationPortRef notifyPort, const io_name_t notificationType, + IOServiceMatchingCallback callback, void * refCon, io_iterator_t * notification) { + + CFDictionaryRef matching = CreateDict(); + IOServiceAddMatchingNotification(notifyPort, notificationType, matching, callback, refCon, notification); + CFRelease(matching); // expected-warning{{used after it is released}} +} + +//===----------------------------------------------------------------------===// +// Test of handling objects whose references "escape" to containers. +//===----------------------------------------------------------------------===// + +void CFDictionaryAddValue(CFMutableDictionaryRef, void *, void *); + +// <rdar://problem/6539791> +void rdar_6539791(CFMutableDictionaryRef y, void* key, void* val_key) { + CFMutableDictionaryRef x = CFDictionaryCreateMutable(kCFAllocatorDefault, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFDictionaryAddValue(y, key, x); + CFRelease(x); // the dictionary keeps a reference, so the object isn't deallocated yet + signed z = 1; + CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); + if (value) { + CFDictionaryAddValue(x, val_key, (void*)value); // no-warning + CFRelease(value); + CFDictionaryAddValue(y, val_key, (void*)value); // no-warning + } +} + +// <rdar://problem/6560661> +// Same issue, except with "AppendValue" functions. +void rdar_6560661(CFMutableArrayRef x) { + signed z = 1; + CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); + // CFArrayAppendValue keeps a reference to value. + CFArrayAppendValue(x, value); + CFRelease(value); + CFRetain(value); + CFRelease(value); // no-warning +} + +// <rdar://problem/7152619> +// Same issue, excwept with "CFAttributeStringSetAttribute". +void rdar_7152619(CFStringRef str) { + CFAttributedStringRef string = CFAttributedStringCreate(kCFAllocatorDefault, str, 0); + CFMutableAttributedStringRef attrString = CFAttributedStringCreateMutableCopy(kCFAllocatorDefault, 100, string); + CFRelease(string); + NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}} + CFAttributedStringSetAttribute(attrString, CFRangeMake(0, 1), str, number); + [number release]; + [number retain]; + CFRelease(attrString); +} + +//===----------------------------------------------------------------------===// +// Test of handling CGGradientXXX functions. +//===----------------------------------------------------------------------===// + +void rdar_7184450(CGContextRef myContext, CGFloat x, CGPoint myStartPoint, + CGPoint myEndPoint) { + size_t num_locations = 6; + CGFloat locations[6] = { 0.0, 0.265, 0.28, 0.31, 0.36, 1.0 }; + CGFloat components[28] = { 239.0/256.0, 167.0/256.0, 170.0/256.0, + x, // Start color + 207.0/255.0, 39.0/255.0, 39.0/255.0, x, + 147.0/255.0, 21.0/255.0, 22.0/255.0, x, + 175.0/255.0, 175.0/255.0, 175.0/255.0, x, + 255.0/255.0,255.0/255.0, 255.0/255.0, x, + 255.0/255.0,255.0/255.0, 255.0/255.0, x + }; // End color + + CGGradientRef myGradient = + CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), // expected-warning{{leak}} + components, locations, num_locations); + + CGContextDrawLinearGradient(myContext, myGradient, myStartPoint, myEndPoint, + 0); + CGGradientRelease(myGradient); +} + +void rdar_7184450_pos(CGContextRef myContext, CGFloat x, CGPoint myStartPoint, + CGPoint myEndPoint) { + size_t num_locations = 6; + CGFloat locations[6] = { 0.0, 0.265, 0.28, 0.31, 0.36, 1.0 }; + CGFloat components[28] = { 239.0/256.0, 167.0/256.0, 170.0/256.0, + x, // Start color + 207.0/255.0, 39.0/255.0, 39.0/255.0, x, + 147.0/255.0, 21.0/255.0, 22.0/255.0, x, + 175.0/255.0, 175.0/255.0, 175.0/255.0, x, + 255.0/255.0,255.0/255.0, 255.0/255.0, x, + 255.0/255.0,255.0/255.0, 255.0/255.0, x + }; // End color + + CGGradientRef myGradient = + CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), components, locations, num_locations); // expected-warning 2 {{leak}} + + CGContextDrawLinearGradient(myContext, myGradient, myStartPoint, myEndPoint, + 0); +} + +//===----------------------------------------------------------------------===// +// <rdar://problem/7299394> clang false positive: retained instance passed to +// thread in pthread_create marked as leak +// +// Until we have full IPA, the analyzer should stop tracking the reference +// count of objects passed to pthread_create. +// +//===----------------------------------------------------------------------===// + +struct _opaque_pthread_t {}; +struct _opaque_pthread_attr_t {}; +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; +} +void rdar_7299394(pthread_attr_t *attr, pthread_t *thread, void *args) { + NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning + pthread_create(thread, attr, rdar_7299394_start_routine, number); +} +void rdar_7299394_positive(pthread_attr_t *attr, pthread_t *thread) { + NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}} +} + +//===----------------------------------------------------------------------===// +// <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 () +// +// According to the Core Video Reference (ADC), CVPixelBufferCreateWithBytes and +// CVPixelBufferCreateWithPlanarBytes can release (via a callback) the +// pixel buffer object. These test cases show how the analyzer stops tracking +// the reference count for the objects passed for this argument. This +// could be made smarter. +//===----------------------------------------------------------------------===// + +typedef int int32_t; +typedef UInt32 FourCharCode; +typedef FourCharCode OSType; +typedef uint64_t CVOptionFlags; +typedef int32_t CVReturn; +typedef struct __CVBuffer *CVBufferRef; +typedef CVBufferRef CVImageBufferRef; +typedef CVImageBufferRef CVPixelBufferRef; +typedef void (*CVPixelBufferReleaseBytesCallback)( void *releaseRefCon, const void *baseAddress ); + +extern CVReturn CVPixelBufferCreateWithBytes(CFAllocatorRef allocator, + size_t width, + size_t height, + OSType pixelFormatType, + void *baseAddress, + size_t bytesPerRow, + CVPixelBufferReleaseBytesCallback releaseCallback, + void *releaseRefCon, + CFDictionaryRef pixelBufferAttributes, + CVPixelBufferRef *pixelBufferOut) ; + +typedef void (*CVPixelBufferReleasePlanarBytesCallback)( void *releaseRefCon, const void *dataPtr, size_t dataSize, size_t numberOfPlanes, const void *planeAddresses[] ); + +extern CVReturn CVPixelBufferCreateWithPlanarBytes(CFAllocatorRef allocator, + size_t width, + size_t height, + OSType pixelFormatType, + void *dataPtr, + size_t dataSize, + size_t numberOfPlanes, + void *planeBaseAddress[], + size_t planeWidth[], + size_t planeHeight[], + size_t planeBytesPerRow[], + CVPixelBufferReleasePlanarBytesCallback releaseCallback, + void *releaseRefCon, + CFDictionaryRef pixelBufferAttributes, + CVPixelBufferRef *pixelBufferOut) ; + +extern CVReturn CVPixelBufferCreateWithBytes(CFAllocatorRef allocator, + size_t width, + size_t height, + OSType pixelFormatType, + void *baseAddress, + size_t bytesPerRow, + CVPixelBufferReleaseBytesCallback releaseCallback, + void *releaseRefCon, + CFDictionaryRef pixelBufferAttributes, + CVPixelBufferRef *pixelBufferOut) ; + +CVReturn rdar_7283567(CFAllocatorRef allocator, size_t width, size_t height, + OSType pixelFormatType, void *baseAddress, + size_t bytesPerRow, + CVPixelBufferReleaseBytesCallback releaseCallback, + CFDictionaryRef pixelBufferAttributes, + CVPixelBufferRef *pixelBufferOut) { + + // For the allocated object, it doesn't really matter what type it is + // for the purpose of this test. All we want to show is that + // this is freed later by the callback. + NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning + + return CVPixelBufferCreateWithBytes(allocator, width, height, pixelFormatType, + baseAddress, bytesPerRow, releaseCallback, + number, // potentially released by callback + pixelBufferAttributes, pixelBufferOut) ; +} + +CVReturn rdar_7283567_2(CFAllocatorRef allocator, size_t width, size_t height, + OSType pixelFormatType, void *dataPtr, size_t dataSize, + size_t numberOfPlanes, void *planeBaseAddress[], + size_t planeWidth[], size_t planeHeight[], size_t planeBytesPerRow[], + CVPixelBufferReleasePlanarBytesCallback releaseCallback, + CFDictionaryRef pixelBufferAttributes, + CVPixelBufferRef *pixelBufferOut) { + + // For the allocated object, it doesn't really matter what type it is + // for the purpose of this test. All we want to show is that + // this is freed later by the callback. + NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning + + return CVPixelBufferCreateWithPlanarBytes(allocator, + width, height, pixelFormatType, dataPtr, dataSize, + numberOfPlanes, planeBaseAddress, planeWidth, + planeHeight, planeBytesPerRow, releaseCallback, + number, // potentially released by callback + pixelBufferAttributes, pixelBufferOut) ; +} + +//===----------------------------------------------------------------------===// +// <rdar://problem/7358899> False leak associated with +// CGBitmapContextCreateWithData +//===----------------------------------------------------------------------===// +typedef uint32_t CGBitmapInfo; +typedef void (*CGBitmapContextReleaseDataCallback)(void *releaseInfo, void *data); + +CGContextRef CGBitmapContextCreateWithData(void *data, + size_t width, size_t height, size_t bitsPerComponent, + size_t bytesPerRow, CGColorSpaceRef space, CGBitmapInfo bitmapInfo, + CGBitmapContextReleaseDataCallback releaseCallback, void *releaseInfo); + +void rdar_7358899(void *data, + size_t width, size_t height, size_t bitsPerComponent, + size_t bytesPerRow, CGColorSpaceRef space, CGBitmapInfo bitmapInfo, + CGBitmapContextReleaseDataCallback releaseCallback) { + + // For the allocated object, it doesn't really matter what type it is + // for the purpose of this test. All we want to show is that + // this is freed later by the callback. + NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning + + CGBitmapContextCreateWithData(data, width, height, bitsPerComponent, // expected-warning{{leak}} + bytesPerRow, space, bitmapInfo, releaseCallback, number); +} + +//===----------------------------------------------------------------------===// +// <rdar://problem/7265711> allow 'new', 'copy', 'alloc', 'init' prefix to +// start before '_' when determining Cocoa fundamental rule +// +// Previously the retain/release checker just skipped prefixes before the +// first '_' entirely. Now the checker honors the prefix if it results in a +// recognizable naming convention (e.g., 'new', 'init'). +//===----------------------------------------------------------------------===// + +@interface RDar7265711 {} +- (id) new_stuff; +@end + +void rdar7265711_a(RDar7265711 *x) { + id y = [x new_stuff]; // expected-warning{{leak}} +} + +void rdar7265711_b(RDar7265711 *x) { + id y = [x new_stuff]; // no-warning + [y release]; +} + +//===----------------------------------------------------------------------===// +// <rdar://problem/7306898> clang thinks [NSCursor dragCopyCursor] returns a +// retained reference +//===----------------------------------------------------------------------===// + +@interface NSCursor : NSObject ++ (NSCursor *)dragCopyCursor; +@end + +void rdar7306898(void) { + // 'dragCopyCursor' does not follow Cocoa's fundamental rule. It is a noun, not an sentence + // implying a 'copy' of something. + NSCursor *c = [NSCursor dragCopyCursor]; // no-warning + NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}} +} + +//===----------------------------------------------------------------------===// +// <rdar://problem/7252064> sending 'release', 'retain', etc. to a Class +// directly is not likely what the user intended +//===----------------------------------------------------------------------===// + +@interface RDar7252064 : NSObject @end +void rdar7252064(void) { + [RDar7252064 release]; // expected-warning{{The 'release' message should be sent to instances of class 'RDar7252064' and not the class directly}} + [RDar7252064 retain]; // expected-warning{{The 'retain' message should be sent to instances of class 'RDar7252064' and not the class directly}} + [RDar7252064 autorelease]; // expected-warning{{The 'autorelease' message should be sent to instances of class 'RDar7252064' and not the class directly}} + [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}} +} + +//===----------------------------------------------------------------------===// +// Tests of ownership attributes. +//===----------------------------------------------------------------------===// + +typedef NSString* MyStringTy; + +@protocol FooP; + +@interface TestOwnershipAttr : NSObject +- (NSString*) returnsAnOwnedString NS_RETURNS_RETAINED; // no-warning +- (NSString*) returnsAnOwnedCFString CF_RETURNS_RETAINED; // no-warning +- (MyStringTy) returnsAnOwnedTypedString NS_RETURNS_RETAINED; // no-warning +- (NSString*) newString NS_RETURNS_NOT_RETAINED; // no-warning +- (NSString*) newString_auto NS_RETURNS_AUTORELEASED; // no-warning +- (NSString*) newStringNoAttr; +- (int) returnsAnOwnedInt NS_RETURNS_RETAINED; // expected-warning{{'ns_returns_retained' attribute only applies to methods that return an Objective-C object}} +- (id) pseudoInit NS_CONSUMES_SELF NS_RETURNS_RETAINED; ++ (void) consume:(id) NS_CONSUMED x; ++ (void) consume2:(id) CF_CONSUMED x; +@end + +static int ownership_attribute_doesnt_go_here NS_RETURNS_RETAINED; // expected-warning{{'ns_returns_retained' attribute only applies to functions and methods}} + +void test_attr_1(TestOwnershipAttr *X) { + NSString *str = [X returnsAnOwnedString]; // expected-warning{{leak}} +} + +void test_attr_1b(TestOwnershipAttr *X) { + NSString *str = [X returnsAnOwnedCFString]; // expected-warning{{leak}} +} + +void test_attr1c(TestOwnershipAttr *X) { + NSString *str = [X newString]; // no-warning + NSString *str2 = [X newStringNoAttr]; // expected-warning{{leak}} + NSString *str3 = [X newString_auto]; // no-warning + NSString *str4 = [[X newString_auto] retain]; // expected-warning {{leak}} +} + +void testattr2_a() { + TestOwnershipAttr *x = [TestOwnershipAttr alloc]; // expected-warning{{leak}} +} + +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]; +} + +void testattr3() { + TestOwnershipAttr *x = [TestOwnershipAttr alloc]; // no-warning + [TestOwnershipAttr consume:x]; + TestOwnershipAttr *y = [TestOwnershipAttr alloc]; // no-warning + [TestOwnershipAttr consume2:y]; +} + +void consume_ns(id NS_CONSUMED x); +void consume_cf(id CF_CONSUMED x); + +void testattr4() { + TestOwnershipAttr *x = [TestOwnershipAttr alloc]; // no-warning + consume_ns(x); + TestOwnershipAttr *y = [TestOwnershipAttr alloc]; // no-warning + consume_cf(y); +} + +@interface TestOwnershipAttr2 : NSObject +- (NSString*) newString NS_RETURNS_NOT_RETAINED; // no-warning +@end + +@implementation TestOwnershipAttr2 +- (NSString*) newString { + return [NSString alloc]; // expected-warning {{Potential leak of an object}} +} +@end + +@interface MyClassTestCFAttr : NSObject {} +- (NSDate*) returnsCFRetained CF_RETURNS_RETAINED; +- (CFDateRef) returnsCFRetainedAsCF CF_RETURNS_RETAINED; +- (CFDateRef) newCFRetainedAsCF CF_RETURNS_NOT_RETAINED; +- (CFDateRef) newCFRetainedAsCFNoAttr; +- (NSDate*) alsoReturnsRetained; +- (CFDateRef) alsoReturnsRetainedAsCF; +- (NSDate*) returnsNSRetained NS_RETURNS_RETAINED; +@end + +CF_RETURNS_RETAINED +CFDateRef returnsRetainedCFDate() { + return CFDateCreate(0, CFAbsoluteTimeGetCurrent()); +} + +@implementation MyClassTestCFAttr +- (NSDate*) returnsCFRetained { + return (NSDate*) returnsRetainedCFDate(); // No leak. +} + +- (CFDateRef) returnsCFRetainedAsCF { + return returnsRetainedCFDate(); // No leak. +} + +- (CFDateRef) newCFRetainedAsCF { + return (CFDateRef)[(id)[self returnsCFRetainedAsCF] autorelease]; +} + +- (CFDateRef) newCFRetainedAsCFNoAttr { + 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}} +} + +- (NSDate*) alsoReturnsRetained { + return (NSDate*) returnsRetainedCFDate(); // expected-warning{{leak}} +} + +- (CFDateRef) alsoReturnsRetainedAsCF { + return returnsRetainedCFDate(); // expected-warning{{leak}} +} + + +- (NSDate*) returnsNSRetained { + return (NSDate*) returnsRetainedCFDate(); // no-warning +} +@end + +//===----------------------------------------------------------------------===// +// Test that leaks post-dominated by "panic" functions are not reported. +// +// <rdar://problem/5905851> do not report a leak when post-dominated by a call +// to a noreturn or panic function +//===----------------------------------------------------------------------===// + +void panic() __attribute__((noreturn)); +void panic_not_in_hardcoded_list() __attribute__((noreturn)); + +void test_panic_negative() { + signed z = 1; + CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // expected-warning{{leak}} +} + +void test_panic_positive() { + signed z = 1; + CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // no-warning + panic(); +} + +void test_panic_neg_2(int x) { + signed z = 1; + CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // expected-warning{{leak}} + if (x) + panic(); +} + +void test_panic_pos_2(int x) { + signed z = 1; + CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // no-warning + if (x) + panic(); + if (!x) { + // This showed up in <rdar://problem/7796563>, where we silently missed checking + // the function type for noreturn. "panic()" is a hard-coded known panic function + // that isn't always noreturn. + panic_not_in_hardcoded_list(); + } +} + +//===----------------------------------------------------------------------===// +// Test uses of blocks (closures) +//===----------------------------------------------------------------------===// + +void test_blocks_1_pos(void) { + NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}} + ^{}(); +} + +void test_blocks_1_indirect_release(void) { + NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning + ^{ [number release]; }(); +} + +void test_blocks_1_indirect_retain(void) { + // Eventually this should be reported as a leak. + NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning + ^{ [number retain]; }(); +} + +void test_blocks_1_indirect_release_via_call(void) { + NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning + ^(NSObject *o){ [o release]; }(number); +} + +void test_blocks_1_indirect_retain_via_call(void) { + NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning {{leak}} + ^(NSObject *o){ [o retain]; }(number); +} + +//===--------------------------------------------------------------------===// +// Test sending message to super that returns an object alias. Previously +// this caused a crash in the analyzer. +//===--------------------------------------------------------------------===// + +@interface Rdar8015556 : NSObject {} @end +@implementation Rdar8015556 +- (id)retain { + return [super retain]; +} +@end + +// <rdar://problem/8272168> - Correcly handle Class<...> in Cocoa Conventions +// detector. + +@protocol Prot_R8272168 @end +Class <Prot_R8272168> GetAClassThatImplementsProt_R8272168(); +void r8272168() { + GetAClassThatImplementsProt_R8272168(); +} + +// Test case for <rdar://problem/8356342>, which in the past triggered +// a false positive. +@interface RDar8356342 +- (NSDate*) rdar8356342:(NSDate *)inValue; +@end + +@implementation RDar8356342 +- (NSDate*) rdar8356342:(NSDate*)inValue { + NSDate *outValue = inValue; + if (outValue == 0) + outValue = [[NSDate alloc] init]; // no-warning + + if (outValue != inValue) + [outValue autorelease]; + + return outValue; +} +@end + +// <rdar://problem/8724287> - This test case previously crashed because +// of a bug in BugReporter. +extern const void *CFDictionaryGetValue(CFDictionaryRef theDict, const void *key); +typedef struct __CFError * CFErrorRef; +extern const CFStringRef kCFErrorUnderlyingErrorKey; +extern CFDictionaryRef CFErrorCopyUserInfo(CFErrorRef err); +static void rdar_8724287(CFErrorRef error) +{ + CFErrorRef error_to_dump; + + error_to_dump = error; + while (error_to_dump != ((void*)0)) { + CFDictionaryRef info; + + info = CFErrorCopyUserInfo(error_to_dump); // expected-warning{{Potential leak of an object}} + + if (info != ((void*)0)) { + } + + error_to_dump = (CFErrorRef) CFDictionaryGetValue(info, kCFErrorUnderlyingErrorKey); + } +} + +// <rdar://problem/9234108> - Make sure the model applies cf_consumed +// correctly in argument positions besides the first. +extern void *CFStringCreate(void); +extern void rdar_9234108_helper(void *key, void * CF_CONSUMED value); +void rdar_9234108() { + rdar_9234108_helper(0, CFStringCreate()); +} + +// <rdar://problem/9726279> - Make sure that objc_method_family works +// to override naming conventions. +struct TwoDoubles { + double one; + double two; +}; +typedef struct TwoDoubles TwoDoubles; + +@interface NSValue (Mine) +- (id)_prefix_initWithTwoDoubles:(TwoDoubles)twoDoubles __attribute__((objc_method_family(init))); +@end + +@implementation NSValue (Mine) +- (id)_prefix_initWithTwoDoubles:(TwoDoubles)twoDoubles +{ + return [self init]; +} +@end + +void rdar9726279() { + TwoDoubles twoDoubles = { 0.0, 0.0 }; + NSValue *value = [[NSValue alloc] _prefix_initWithTwoDoubles:twoDoubles]; + [value release]; +} + +// <rdar://problem/9732321> +// Test camelcase support for CF conventions. While Core Foundation APIs +// don't use camel casing, other code is allowed to use it. +CFArrayRef camelcase_create_1() { + return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning +} + +CFArrayRef camelcase_createno() { + return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning {{leak}} +} + +CFArrayRef camelcase_copy() { + return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning +} + +CFArrayRef camelcase_copying() { + return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning {{leak}} +} + +CFArrayRef copyCamelCase() { + return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning +} + +CFArrayRef __copyCamelCase() { + return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning +} + +CFArrayRef __createCamelCase() { + return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning +} + +CFArrayRef camel_create() { + return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning +} + + +CFArrayRef camel_creat() { + return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning {{leak}} +} + +CFArrayRef camel_copy() { + return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning +} + +CFArrayRef camel_copyMachine() { + return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning +} + +CFArrayRef camel_copymachine() { + return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning {{leak}} +} + +// rdar://problem/8024350 +@protocol F18P +- (id) clone; +@end +@interface F18 : NSObject<F18P> @end +@interface F18(Cat) +- (id) clone NS_RETURNS_RETAINED; +@end + +@implementation F18 +- (id) clone { + return [F18 alloc]; +} +@end + +// Radar 6582778. +void rdar6582778(void) { + CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); + CFTypeRef vals[] = { CFDateCreate(0, t) }; // expected-warning {{leak}} +} + +CFTypeRef global; + +void rdar6582778_2(void) { + CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); + global = CFDateCreate(0, t); // no-warning +} + +// <rdar://problem/10232019> - Test that objects passed to containers +// are marked "escaped". + +void rdar10232019() { + NSMutableArray *array = [NSMutableArray array]; + + NSString *string = [[NSString alloc] initWithUTF8String:"foo"]; + [array addObject:string]; + [string release]; + + NSString *otherString = [string stringByAppendingString:@"bar"]; // no-warning + NSLog(@"%@", otherString); +} + +void rdar10232019_positive() { + NSMutableArray *array = [NSMutableArray array]; + + NSString *string = [[NSString alloc] initWithUTF8String:"foo"]; + [string release]; + + NSString *otherString = [string stringByAppendingString:@"bar"]; // expected-warning {{Reference-counted object is used after it is release}} + NSLog(@"%@", otherString); +} + +// RetainCountChecker support for XPC. +// <rdar://problem/9658496> +typedef void * xpc_object_t; +xpc_object_t _CFXPCCreateXPCObjectFromCFObject(CFTypeRef cf); +void xpc_release(xpc_object_t object); + +void rdar9658496() { + CFStringRef cf; + xpc_object_t xpc; + cf = CFStringCreateWithCString( ((CFAllocatorRef)0), "test", kCFStringEncodingUTF8 ); // no-warning + xpc = _CFXPCCreateXPCObjectFromCFObject( cf ); + CFRelease(cf); + xpc_release(xpc); +} + +// Support annotations with method families. +@interface RDar10824732 : NSObject +- (id)initWithObj:(id CF_CONSUMED)obj; +@end + +@implementation RDar10824732 +- (id)initWithObj:(id)obj { + [obj release]; + return [super init]; +} +@end + +void rdar_10824732() { + @autoreleasepool { + NSString *obj = @"test"; + RDar10824732 *foo = [[RDar10824732 alloc] initWithObj:obj]; // no-warning + [foo release]; + } +} + +// 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]; +} + +- (id)copyAutoreleaseRadar13081402 { + id x = [[[NSString alloc] initWithUTF8String:"foo"] autorelease]; + [x retain]; + return x; // no warning +} + +@end +//===----------------------------------------------------------------------===// +// Test returning allocated memory in a struct. +// +// We currently don't have a general way to track pointers that "escape". +// Here we test that RetainCountChecker doesn't get excited about returning +// allocated CF objects in struct fields. +//===----------------------------------------------------------------------===// +void *malloc(size_t); +struct rdar11104566 { CFStringRef myStr; }; +struct rdar11104566 test_rdar11104566() { + CFStringRef cf = CFStringCreateWithCString( ((CFAllocatorRef)0), "test", kCFStringEncodingUTF8 ); // no-warning + struct rdar11104566 V; + V.myStr = cf; + return V; // no-warning +} + +struct rdar11104566 *test_2_rdar11104566() { + CFStringRef cf = CFStringCreateWithCString( ((CFAllocatorRef)0), "test", kCFStringEncodingUTF8 ); // no-warning + struct rdar11104566 *V = (struct rdar11104566 *) malloc(sizeof(*V)); + V->myStr = cf; + return V; // no-warning +} + +//===----------------------------------------------------------------------===// +// ObjC literals support. +//===----------------------------------------------------------------------===// + +void test_objc_arrays() { + { // CASE ONE -- OBJECT IN ARRAY CREATED DIRECTLY + NSObject *o = [[NSObject alloc] init]; + NSArray *a = [[NSArray alloc] initWithObjects:o, (void*)0]; // expected-warning {{leak}} + [o release]; + [a description]; + [o description]; + } + + { // CASE TWO -- OBJECT IN ARRAY CREATED BY DUPING AUTORELEASED ARRAY + NSObject *o = [[NSObject alloc] init]; + NSArray *a1 = [NSArray arrayWithObjects:o, (void*)0]; + NSArray *a2 = [[NSArray alloc] initWithArray:a1]; // expected-warning {{leak}} + [o release]; + [a2 description]; + [o description]; + } + + { // CASE THREE -- OBJECT IN RETAINED @[] + NSObject *o = [[NSObject alloc] init]; + NSArray *a3 = [@[o] retain]; // expected-warning {{leak}} + [o release]; + [a3 description]; + [o description]; + } + + { // CASE FOUR -- OBJECT IN ARRAY CREATED BY DUPING @[] + NSObject *o = [[NSObject alloc] init]; + NSArray *a = [[NSArray alloc] initWithArray:@[o]]; // expected-warning {{leak}} + [o release]; + + [a description]; + [o description]; + } + + { // CASE FIVE -- OBJECT IN RETAINED @{} + NSValue *o = [[NSValue alloc] init]; + NSDictionary *a = [@{o : o} retain]; // expected-warning {{leak}} + [o release]; + + [a description]; + [o description]; + } +} + +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 +} + + +void consumeAndStopTracking(id NS_CONSUMED obj, void (^callback)(void)); +void CFConsumeAndStopTracking(CFTypeRef CF_CONSUMED obj, void (^callback)(void)); + +void testConsumeAndStopTracking() { + id retained = [@[] retain]; // +1 + consumeAndStopTracking(retained, ^{}); // no-warning + + id doubleRetained = [[@[] retain] retain]; // +2 + consumeAndStopTracking(doubleRetained, ^{ + [doubleRetained release]; + }); // no-warning + + id unretained = @[]; // +0 + consumeAndStopTracking(unretained, ^{}); // expected-warning {{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} +} + +void testCFConsumeAndStopTracking() { + id retained = [@[] retain]; // +1 + CFConsumeAndStopTracking((CFTypeRef)retained, ^{}); // no-warning + + id doubleRetained = [[@[] retain] retain]; // +2 + CFConsumeAndStopTracking((CFTypeRef)doubleRetained, ^{ + [doubleRetained release]; + }); // no-warning + + id unretained = @[]; // +0 + CFConsumeAndStopTracking((CFTypeRef)unretained, ^{}); // expected-warning {{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} +} +//===----------------------------------------------------------------------===// +// Test 'pragma clang arc_cf_code_audited' support. +//===----------------------------------------------------------------------===// + +typedef void *MyCFType; +#pragma clang arc_cf_code_audited begin +MyCFType CreateMyCFType(); +#pragma clang arc_cf_code_audited end + +void test_custom_cf() { + MyCFType x = CreateMyCFType(); // expected-warning {{leak of an object stored into 'x'}} +} + +//===----------------------------------------------------------------------===// +// Test calling CFPlugInInstanceCreate, which appears in CF but doesn't +// return a CF object. +//===----------------------------------------------------------------------===// + +void test_CFPlugInInstanceCreate(CFUUIDRef factoryUUID, CFUUIDRef typeUUID) { + CFPlugInInstanceCreate(kCFAllocatorDefault, factoryUUID, typeUUID); // no-warning +} + +//===----------------------------------------------------------------------===// +// PR14927: -drain only has retain-count semantics on NSAutoreleasePool. +//===----------------------------------------------------------------------===// + +@interface PR14927 : NSObject +- (void)drain; +@end + +void test_drain() { + PR14927 *obj = [[PR14927 alloc] init]; + [obj drain]; + [obj release]; // no-warning +} + +//===----------------------------------------------------------------------===// +// Allow cf_returns_retained and cf_returns_not_retained to mark a return +// value as tracked, even if the object isn't a known CF type. +//===----------------------------------------------------------------------===// + +MyCFType getCustom() __attribute__((cf_returns_not_retained)); +MyCFType makeCustom() __attribute__((cf_returns_retained)); + +void testCustomReturnsRetained() { + MyCFType obj = makeCustom(); // expected-warning {{leak of an object stored into 'obj'}} +} + +void testCustomReturnsNotRetained() { + CFRelease(getCustom()); // expected-warning {{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} +} + +//===----------------------------------------------------------------------===// +// Don't print variables which are out of the current scope. +//===----------------------------------------------------------------------===// +@interface MyObj12706177 : NSObject +-(id)initX; ++(void)test12706177; +@end +static int Cond; +@implementation MyObj12706177 +-(id)initX { + if (Cond) + return 0; + self = [super init]; + return self; +} ++(void)test12706177 { + id x = [[MyObj12706177 alloc] initX]; //expected-warning {{Potential leak of an object}} + [x release]; +} +@end + +//===----------------------------------------------------------------------===// +// <rdar://problem/13783514> xpc_connection_set_finalizer_f +//===----------------------------------------------------------------------===// + +typedef xpc_object_t xpc_connection_t; +typedef void (*xpc_finalizer_t)(void *value); +void xpc_connection_set_context(xpc_connection_t connection, void *ctx); +void xpc_connection_set_finalizer_f(xpc_connection_t connection, + xpc_finalizer_t finalizer); +void releaseAfterXPC(void *context) { + [(NSArray *)context release]; +} + +void rdar13783514(xpc_connection_t connection) { + xpc_connection_set_context(connection, [[NSMutableArray alloc] init]); + xpc_connection_set_finalizer_f(connection, releaseAfterXPC); +} // no-warning + +CFAttributedStringRef CFAttributedCreate(void *CFObj CF_CONSUMED) CF_RETURNS_RETAINED; + +@interface Action +- (SEL)action; +- (void)setAction:(SEL)aSelector; +- (id) target; +- (void)setTarget:(id)aTarget; +@end diff --git a/test/ARCMT/objcmt-arc-cf-annotations.m.result b/test/ARCMT/objcmt-arc-cf-annotations.m.result new file mode 100644 index 0000000..7e0a904 --- /dev/null +++ b/test/ARCMT/objcmt-arc-cf-annotations.m.result @@ -0,0 +1,2093 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fblocks -objcmt-migrate-annotation -objcmt-migrate-instancetype -objcmt-migrate-readwrite-property -mt-migrate-directory %t %s -x objective-c -triple x86_64-apple-darwin11 +// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result +// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s.result + +#ifndef CF_IMPLICIT_BRIDGING_ENABLED +#if __has_feature(arc_cf_code_audited) +#define CF_IMPLICIT_BRIDGING_ENABLED _Pragma("clang arc_cf_code_audited begin") +#else +#define CF_IMPLICIT_BRIDGING_ENABLED +#endif +#endif + +#ifndef CF_IMPLICIT_BRIDGING_DISABLED +#if __has_feature(arc_cf_code_audited) +#define CF_IMPLICIT_BRIDGING_DISABLED _Pragma("clang arc_cf_code_audited end") +#else +#define CF_IMPLICIT_BRIDGING_DISABLED +#endif +#endif + +#if __has_feature(attribute_ns_returns_retained) +#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained)) +#endif +#if __has_feature(attribute_cf_returns_retained) +#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained)) +#endif +#if __has_feature(attribute_ns_returns_not_retained) +#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained)) +#endif +#if __has_feature(attribute_cf_returns_not_retained) +#define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained)) +#endif +#if __has_feature(attribute_ns_consumes_self) +#define NS_CONSUMES_SELF __attribute__((ns_consumes_self)) +#endif +#if __has_feature(attribute_ns_consumed) +#define NS_CONSUMED __attribute__((ns_consumed)) +#endif +#if __has_feature(attribute_cf_consumed) +#define CF_CONSUMED __attribute__((cf_consumed)) +#endif +#if __has_attribute(ns_returns_autoreleased) +#define NS_RETURNS_AUTORELEASED __attribute__((ns_returns_autoreleased)) +#endif + +//===----------------------------------------------------------------------===// +// The following code is reduced using delta-debugging from Mac OS X headers: +// +// #include <Cocoa/Cocoa.h> +// #include <CoreFoundation/CoreFoundation.h> +// #include <DiskArbitration/DiskArbitration.h> +// #include <QuartzCore/QuartzCore.h> +// #include <Quartz/Quartz.h> +// #include <IOKit/IOKitLib.h> +// +// It includes the basic definitions for the test cases below. +//===----------------------------------------------------------------------===// + +typedef unsigned int __darwin_natural_t; +typedef unsigned long uintptr_t; +typedef unsigned int uint32_t; +typedef unsigned long long uint64_t; +typedef unsigned int UInt32; +typedef signed long CFIndex; +typedef CFIndex CFByteOrder; +typedef struct { + CFIndex location; + CFIndex length; +} CFRange; +static __inline__ __attribute__((always_inline)) CFRange CFRangeMake(CFIndex loc, CFIndex len) { + CFRange range; + range.location = loc; + range.length = len; + return range; +} +typedef const void * CFTypeRef; +typedef const struct __CFString * CFStringRef; +typedef const struct __CFAllocator * CFAllocatorRef; +extern const CFAllocatorRef kCFAllocatorDefault; +extern CFTypeRef CFRetain(CFTypeRef cf); + +CF_IMPLICIT_BRIDGING_ENABLED + +extern void CFRelease(CFTypeRef cf); + +CF_IMPLICIT_BRIDGING_DISABLED + +extern CFTypeRef CFMakeCollectable(CFTypeRef cf); +typedef struct { +} +CFArrayCallBacks; +extern const CFArrayCallBacks kCFTypeArrayCallBacks; +typedef const struct __CFArray * CFArrayRef; +typedef struct __CFArray * CFMutableArrayRef; +extern CFMutableArrayRef CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFArrayCallBacks *callBacks) CF_RETURNS_RETAINED; +extern const void *CFArrayGetValueAtIndex(CFArrayRef theArray, CFIndex idx) CF_RETURNS_NOT_RETAINED; +extern void CFArrayAppendValue(CFMutableArrayRef theArray, const void *value); +typedef struct { +} +CFDictionaryKeyCallBacks; +extern const CFDictionaryKeyCallBacks kCFTypeDictionaryKeyCallBacks; +typedef struct { +} +CFDictionaryValueCallBacks; +extern const CFDictionaryValueCallBacks kCFTypeDictionaryValueCallBacks; +typedef const struct __CFDictionary * CFDictionaryRef; +typedef struct __CFDictionary * CFMutableDictionaryRef; +extern CFMutableDictionaryRef CFDictionaryCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFDictionaryKeyCallBacks *keyCallBacks, const CFDictionaryValueCallBacks *valueCallBacks) CF_RETURNS_RETAINED; +typedef UInt32 CFStringEncoding; +enum { +kCFStringEncodingMacRoman = 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 }; +extern CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding) CF_RETURNS_RETAINED; +typedef double CFTimeInterval; +typedef CFTimeInterval CFAbsoluteTime; +extern CFAbsoluteTime CFAbsoluteTimeGetCurrent(void); +typedef const struct __CFDate * CFDateRef; +extern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at) CF_RETURNS_RETAINED; +extern CFAbsoluteTime CFDateGetAbsoluteTime(CFDateRef theDate); +typedef __darwin_natural_t natural_t; +typedef natural_t mach_port_name_t; +typedef mach_port_name_t mach_port_t; +typedef int kern_return_t; +typedef kern_return_t mach_error_t; +enum { +kCFNumberSInt8Type = 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 }; +typedef CFIndex CFNumberType; +typedef const struct __CFNumber * CFNumberRef; +extern CFNumberRef CFNumberCreate(CFAllocatorRef allocator, CFNumberType theType, const void *valuePtr) CF_RETURNS_RETAINED; +typedef const struct __CFAttributedString *CFAttributedStringRef; +typedef struct __CFAttributedString *CFMutableAttributedStringRef; +extern CFAttributedStringRef CFAttributedStringCreate(CFAllocatorRef alloc, CFStringRef str, CFDictionaryRef attributes) CF_RETURNS_RETAINED ; +extern CFMutableAttributedStringRef CFAttributedStringCreateMutableCopy(CFAllocatorRef alloc, CFIndex maxLength, CFAttributedStringRef aStr) CF_RETURNS_RETAINED ; +extern void CFAttributedStringSetAttribute(CFMutableAttributedStringRef aStr, CFRange range, CFStringRef attrName, CFTypeRef value) ; +typedef signed char BOOL; +typedef unsigned long NSUInteger; +@class NSString, Protocol; +extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2))); +typedef struct _NSZone NSZone; +@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; +@protocol NSObject +- (BOOL)isEqual:(id)object; +- (id)retain; +- (oneway void)release; +- (id)autorelease; +- (NSString *)description; +- (instancetype)init; +@end +@protocol NSCopying +- (id)copyWithZone:(NSZone *)zone; +@end +@protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; +@end +@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; +@end +@interface NSObject <NSObject> {} ++ (id)allocWithZone:(NSZone *)zone; ++ (id)alloc; ++ (id)new; +- (void)dealloc; +@end +@interface NSObject (NSCoderMethods) +- (id)awakeAfterUsingCoder:(NSCoder *)aDecoder; +@end +extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone); +typedef struct { +} +NSFastEnumerationState; +@protocol NSFastEnumeration +- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len; +@end +@class NSString, NSDictionary; +@interface NSValue : NSObject <NSCopying, NSCoding> - (void)getValue:(void *)value; +@end +@interface NSNumber : NSValue +- (char)charValue; +- (instancetype)initWithInt:(int)value; ++ (NSNumber *)numberWithInt:(int)value; +@end +@class NSString; +@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration> +- (NSUInteger)count; +- (instancetype)initWithObjects:(const id [])objects count:(NSUInteger)cnt; ++ (instancetype)arrayWithObject:(id)anObject; ++ (instancetype)arrayWithObjects:(const id [])objects count:(NSUInteger)cnt; ++ (instancetype)arrayWithObjects:(id)firstObj, ... __attribute__((sentinel(0,1))); +- (instancetype)initWithObjects:(id)firstObj, ... __attribute__((sentinel(0,1))); +- (instancetype)initWithArray:(NSArray *)array; +@end @interface NSArray (NSArrayCreation) + (instancetype)array; +@end @interface NSAutoreleasePool : NSObject { +} +- (void)drain; +@end extern NSString * const NSBundleDidLoadNotification; +typedef double NSTimeInterval; +@interface NSDate : NSObject <NSCopying, NSCoding> - (NSTimeInterval)timeIntervalSinceReferenceDate; +@end typedef unsigned short unichar; +@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding> +- (NSUInteger)length; +- (NSString *)stringByAppendingString:(NSString *)aString; +- ( const char *)UTF8String; +- (instancetype)initWithUTF8String:(const char *)nullTerminatedCString; ++ (instancetype)stringWithUTF8String:(const char *)nullTerminatedCString; +@end @class NSString, NSURL, NSError; +@interface NSData : NSObject <NSCopying, NSMutableCopying, NSCoding> - (NSUInteger)length; ++ (instancetype)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length; ++ (instancetype)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length freeWhenDone:(BOOL)b; +@end @class NSLocale, NSDate, NSCalendar, NSTimeZone, NSError, NSArray, NSMutableDictionary; +@interface NSDictionary : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration> +- (NSUInteger)count; ++ (instancetype)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; ++ (instancetype)dictionaryWithObjects:(const id [])objects forKeys:(const id <NSCopying> [])keys count:(NSUInteger)cnt; +@end +@interface NSMutableDictionary : NSDictionary - (void)removeObjectForKey:(id)aKey; +- (void)setObject:(id)anObject forKey:(id)aKey; +@end @interface NSMutableDictionary (NSMutableDictionaryCreation) + (instancetype)dictionaryWithCapacity:(NSUInteger)numItems; +@end typedef double CGFloat; +struct CGSize { +}; +typedef struct CGSize CGSize; +struct CGRect { +}; +typedef struct CGRect CGRect; +typedef mach_port_t io_object_t; +typedef char io_name_t[128]; +typedef io_object_t io_iterator_t; +typedef io_object_t io_service_t; +typedef struct IONotificationPort * IONotificationPortRef; +typedef void (*IOServiceMatchingCallback)( void * refcon, io_iterator_t iterator ); + +CF_IMPLICIT_BRIDGING_ENABLED + +io_service_t IOServiceGetMatchingService( mach_port_t masterPort, CFDictionaryRef matching ); +kern_return_t IOServiceGetMatchingServices( mach_port_t masterPort, CFDictionaryRef matching, io_iterator_t * existing ); + +CF_IMPLICIT_BRIDGING_DISABLED + +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 CF_CONSUMED matching, IOServiceMatchingCallback callback, void * refCon, io_iterator_t * notification ); + +CF_IMPLICIT_BRIDGING_ENABLED + +CFMutableDictionaryRef IOServiceMatching( const char * name ); +CFMutableDictionaryRef IOServiceNameMatching( const char * name ); +CFMutableDictionaryRef IOBSDNameMatching( mach_port_t masterPort, uint32_t options, const char * bsdName ); +CFMutableDictionaryRef IOOpenFirmwarePathMatching( mach_port_t masterPort, uint32_t options, const char * path ); +CFMutableDictionaryRef IORegistryEntryIDMatching( uint64_t entryID ); + +CF_IMPLICIT_BRIDGING_DISABLED + +typedef struct __DASession * DASessionRef; +extern DASessionRef DASessionCreate( CFAllocatorRef allocator ) CF_RETURNS_RETAINED; +typedef struct __DADisk * DADiskRef; +extern DADiskRef DADiskCreateFromBSDName( CFAllocatorRef allocator, DASessionRef session, const char * name ) CF_RETURNS_RETAINED; +extern DADiskRef DADiskCreateFromIOMedia( CFAllocatorRef allocator, DASessionRef session, io_service_t media ) CF_RETURNS_RETAINED; +extern CFDictionaryRef DADiskCopyDescription( DADiskRef disk ) CF_RETURNS_RETAINED; +extern DADiskRef DADiskCopyWholeDisk( DADiskRef disk ) CF_RETURNS_RETAINED; +@interface NSTask : NSObject - (instancetype)init; +@end typedef struct CGColorSpace *CGColorSpaceRef; +typedef struct CGImage *CGImageRef; +typedef struct CGLayer *CGLayerRef; +@interface NSResponder : NSObject <NSCoding> { +} +@end @protocol NSAnimatablePropertyContainer - (id)animator; +@end extern NSString *NSAnimationTriggerOrderIn ; +@interface NSView : NSResponder <NSAnimatablePropertyContainer> { +} +@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; +@protocol NSApplicationDelegate <NSObject> @optional - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender; +@end @class NSAttributedString, NSEvent, NSFont, NSFormatter, NSImage, NSMenu, NSText, NSView, NSTextView; +@interface NSCell : NSObject <NSCopying, NSCoding> { +} +@end +typedef struct { +} +CVTimeStamp; +@interface CIImage : NSObject <NSCoding, NSCopying> { +} +typedef int CIFormat; +@end enum { +kDAReturnSuccess = 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 }; +typedef mach_error_t DAReturn; +typedef const struct __DADissenter * DADissenterRef; +extern DADissenterRef DADissenterCreate( CFAllocatorRef allocator, DAReturn status, CFStringRef string ) CF_RETURNS_RETAINED; +@interface CIContext: NSObject { +} +- (CGImageRef)createCGImage:(CIImage *)im fromRect:(CGRect)r CF_RETURNS_RETAINED; +- (CGImageRef)createCGImage:(CIImage *)im fromRect:(CGRect)r format:(CIFormat)f colorSpace:(CGColorSpaceRef)cs CF_RETURNS_RETAINED; +- (CGLayerRef)createCGLayerWithSize:(CGSize)size info:(CFDictionaryRef)d CF_RETURNS_RETAINED; +@end extern NSString* const QCRendererEventKey; +@protocol QCCompositionRenderer - (NSDictionary*) attributes; +@end @interface QCRenderer : NSObject <QCCompositionRenderer> { +} +- (id) createSnapshotImageOfType:(NSString*)type; +@end extern NSString* const QCViewDidStartRenderingNotification; +@interface QCView : NSView <QCCompositionRenderer> { +} +- (id) createSnapshotImageOfType:(NSString*)type; +@end enum { +ICEXIFOrientation1 = 1, ICEXIFOrientation2 = 2, ICEXIFOrientation3 = 3, ICEXIFOrientation4 = 4, ICEXIFOrientation5 = 5, ICEXIFOrientation6 = 6, ICEXIFOrientation7 = 7, ICEXIFOrientation8 = 8, }; +@class ICDevice; +@protocol ICDeviceDelegate <NSObject> @required - (void)didRemoveDevice:(ICDevice*)device; +@end extern NSString *const ICScannerStatusWarmingUp; +@class ICScannerDevice; +@protocol ICScannerDeviceDelegate <ICDeviceDelegate> @optional - (void)scannerDeviceDidBecomeAvailable:(ICScannerDevice*)scanner; +@end + +typedef long unsigned int __darwin_size_t; +typedef __darwin_size_t size_t; +typedef unsigned long CFTypeID; +struct CGPoint { + CGFloat x; + CGFloat y; +}; +typedef struct CGPoint CGPoint; +typedef struct CGGradient *CGGradientRef; +typedef uint32_t CGGradientDrawingOptions; +extern CFTypeID CGGradientGetTypeID(void); +extern CGGradientRef CGGradientCreateWithColorComponents(CGColorSpaceRef + space, const CGFloat components[], const CGFloat locations[], size_t count) CF_RETURNS_RETAINED; +extern CGGradientRef CGGradientCreateWithColors(CGColorSpaceRef space, + CFArrayRef colors, const CGFloat locations[]) CF_RETURNS_RETAINED; +extern CGGradientRef CGGradientRetain(CGGradientRef gradient); + +CF_IMPLICIT_BRIDGING_ENABLED + +extern void CGGradientRelease(CGGradientRef gradient); + +CF_IMPLICIT_BRIDGING_DISABLED + +typedef struct CGContext *CGContextRef; +extern void CGContextDrawLinearGradient(CGContextRef context, + CGGradientRef gradient, CGPoint startPoint, CGPoint endPoint, + CGGradientDrawingOptions options); + +CF_IMPLICIT_BRIDGING_ENABLED + +extern CGColorSpaceRef CGColorSpaceCreateDeviceRGB(void); + +CF_IMPLICIT_BRIDGING_DISABLED + + +@interface NSMutableArray : NSObject +- (void)addObject:(id)object; ++ (instancetype)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)); + +typedef const struct __CFUUID * CFUUIDRef; + +extern +void *CFPlugInInstanceCreate(CFAllocatorRef allocator, CFUUIDRef factoryUUID, CFUUIDRef typeUUID); + +//===----------------------------------------------------------------------===// +// Test cases. +//===----------------------------------------------------------------------===// + +CFAbsoluteTime f1() { + CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); + CFDateRef date = CFDateCreate(0, t); + CFRetain(date); + CFRelease(date); + CFDateGetAbsoluteTime(date); // no-warning + CFRelease(date); + t = CFDateGetAbsoluteTime(date); // expected-warning{{Reference-counted object is used after it is released}} + return t; +} + +CFAbsoluteTime f2() { + CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); + CFDateRef date = CFDateCreate(0, t); + [((NSDate*) date) retain]; + CFRelease(date); + CFDateGetAbsoluteTime(date); // no-warning + [((NSDate*) date) release]; + t = CFDateGetAbsoluteTime(date); // expected-warning{{Reference-counted object is used after it is released}} + return t; +} + + +NSDate* global_x; + +// Test to see if we supresss an error when we store the pointer +// to a global. + +CFAbsoluteTime f3() { + CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); + CFDateRef date = CFDateCreate(0, t); + [((NSDate*) date) retain]; + CFRelease(date); + CFDateGetAbsoluteTime(date); // no-warning + global_x = (NSDate*) date; + [((NSDate*) date) release]; + t = CFDateGetAbsoluteTime(date); // no-warning + return t; +} + +//--------------------------------------------------------------------------- +// Test case 'f4' differs for region store and basic store. See +// retain-release-region-store.m and retain-release-basic-store.m. +//--------------------------------------------------------------------------- + +// Test a leak. + +CFAbsoluteTime f5(int x) { + CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); + CFDateRef date = CFDateCreate(0, t); // expected-warning{{leak}} + + if (x) + CFRelease(date); + + return t; +} + +// Test a leak involving the return. + +CFDateRef f6(int x) { + CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); // expected-warning{{leak}} + CFRetain(date); + return date; +} + +// Test a leak involving an overwrite. + +CFDateRef f7() { + CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); //expected-warning{{leak}} + CFRetain(date); + date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); // expected-warning {{leak}} + return date; +} + +// Generalization of Create rule. MyDateCreate returns a CFXXXTypeRef, and +// has the word create. + +CF_IMPLICIT_BRIDGING_ENABLED + +CFDateRef MyDateCreate(); + +CF_IMPLICIT_BRIDGING_DISABLED + + +CFDateRef f8() { + CFDateRef date = MyDateCreate(); // expected-warning{{leak}} + CFRetain(date); + return date; +} + +__attribute__((cf_returns_retained)) CFDateRef f9() { + CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); // no-warning + int *p = 0; + // When allocations fail, CFDateCreate can return null. + if (!date) *p = 1; // expected-warning{{null}} + return date; +} + +// Handle DiskArbitration API: +// +// http://developer.apple.com/DOCUMENTATION/DARWIN/Reference/DiscArbitrationFramework/ +// +void f10(io_service_t media, DADiskRef d, CFStringRef s) { + DADiskRef disk = DADiskCreateFromBSDName(kCFAllocatorDefault, 0, "hello"); // expected-warning{{leak}} + if (disk) NSLog(@"ok"); + + disk = DADiskCreateFromIOMedia(kCFAllocatorDefault, 0, media); // expected-warning{{leak}} + if (disk) NSLog(@"ok"); + + CFDictionaryRef dict = DADiskCopyDescription(d); // expected-warning{{leak}} + if (dict) NSLog(@"ok"); + + disk = DADiskCopyWholeDisk(d); // expected-warning{{leak}} + if (disk) NSLog(@"ok"); + + DADissenterRef dissenter = DADissenterCreate(kCFAllocatorDefault, // expected-warning{{leak}} + kDAReturnSuccess, s); + if (dissenter) NSLog(@"ok"); + + DASessionRef session = DASessionCreate(kCFAllocatorDefault); // expected-warning{{leak}} + if (session) NSLog(@"ok"); +} + +// Test retain/release checker with CFString and CFMutableArray. +void f11() { + // Create the array. + CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); + + // Create a string. + CFStringRef s1 = CFStringCreateWithCString(0, "hello world", + kCFStringEncodingUTF8); + + // Add the string to the array. + CFArrayAppendValue(A, s1); + + // Decrement the reference count. + CFRelease(s1); // no-warning + + // Get the string. We don't own it. + s1 = (CFStringRef) CFArrayGetValueAtIndex(A, 0); + + // Release the array. + CFRelease(A); // no-warning + + // Release the string. This is a bug. + CFRelease(s1); // expected-warning{{Incorrect decrement of the reference count}} +} + +// PR 3337: Handle functions declared using typedefs. +typedef CFTypeRef CREATEFUN(); + +CF_IMPLICIT_BRIDGING_ENABLED + +CFTypeRef MyCreateFun(); + +CF_IMPLICIT_BRIDGING_DISABLED + + +void f12() { + CFTypeRef o = MyCreateFun(); // expected-warning {{leak}} +} + +void f13_autorelease() { + CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning + [(id) A autorelease]; // no-warning +} + +void f13_autorelease_b() { + CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); + [(id) A autorelease]; + [(id) A autorelease]; +} // expected-warning{{Object autoreleased too many times}} + +CFMutableArrayRef f13_autorelease_c() { + CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); + [(id) A autorelease]; + [(id) A autorelease]; + return A; // expected-warning{{Object autoreleased too many times}} +} + +CFMutableArrayRef f13_autorelease_d() { + CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); + [(id) A autorelease]; + [(id) A autorelease]; + CFMutableArrayRef B = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{Object autoreleased too many times}} + CFRelease(B); // no-warning + while (1) {} +} + + +// This case exercises the logic where the leak site is the same as the allocation site. +void f14_leakimmediately() { + CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{leak}} +} + +// Test that we track an allocated object beyond the point where the *name* +// of the variable storing the reference is no longer live. +void f15() { + // Create the array. + CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); + CFMutableArrayRef *B = &A; + // At this point, the name 'A' is no longer live. + CFRelease(*B); // no-warning +} + +// Test when we pass NULL to CFRetain/CFRelease/CFMakeCollectable. +void f16(int x, CFTypeRef p) { + if (p) + return; + + if (x > 0) { + CFRelease(p); // expected-warning{{Null pointer argument in call to CFRelease}} + } + else if (x < 0) { + CFRetain(p); // expected-warning{{Null pointer argument in call to CFRetain}} + } + else { + CFMakeCollectable(p); // expected-warning{{Null pointer argument in call to CFMakeCollectable}} + } +} + +// Test that an object is non-null after being CFRetained/CFReleased. +void f17(int x, CFTypeRef p) { + if (x > 0) { + CFRelease(p); + if (!p) + CFRelease(0); // no-warning + } + else if (x < 0) { + CFRetain(p); + if (!p) + CFRetain(0); // no-warning + } + else { + CFMakeCollectable(p); + if (!p) + CFMakeCollectable(0); // no-warning + } +} + +// Test basic tracking of ivars associated with 'self'. For the retain/release +// checker we currently do not want to flag leaks associated with stores +// of tracked objects to ivars. +@interface SelfIvarTest : NSObject { + id myObj; +} +- (void)test_self_tracking; +@end + +@implementation SelfIvarTest +- (void)test_self_tracking { + myObj = (id) CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning +} +@end + +// Test return of non-owned objects in contexts where an owned object +// is expected. +@interface TestReturnNotOwnedWhenExpectedOwned +- (NSString*)newString; +@end + +@implementation TestReturnNotOwnedWhenExpectedOwned +- (NSString*)newString { + NSString *s = [NSString stringWithUTF8String:"hello"]; + return s; // expected-warning{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} +} +@end + +// <rdar://problem/6659160> +int isFoo(char c); + +static void rdar_6659160(char *inkind, char *inname) +{ + // We currently expect that [NSObject alloc] cannot fail. This + // will be a toggled flag in the future. It can indeed return null, but + // Cocoa programmers generally aren't expected to reason about out-of-memory + // conditions. + NSString *kind = [[NSString alloc] initWithUTF8String:inkind]; // expected-warning{{leak}} + + // We do allow stringWithUTF8String to fail. This isn't really correct, as + // far as returning 0. In most error conditions it will throw an exception. + // If allocation fails it could return 0, but again this + // isn't expected. + NSString *name = [NSString stringWithUTF8String:inname]; + if(!name) + return; + + const char *kindC = 0; + const char *nameC = 0; + + // In both cases, we cannot reach a point down below where we + // dereference kindC or nameC with either being null. This is because + // we assume that [NSObject alloc] doesn't fail and that we have the guard + // up above. + + if(kind) + kindC = [kind UTF8String]; + if(name) + nameC = [name UTF8String]; + if(!isFoo(kindC[0])) // expected-warning{{null}} + return; + if(!isFoo(nameC[0])) // no-warning + return; + + [kind release]; + [name release]; // expected-warning{{Incorrect decrement of the reference count}} +} + +// PR 3677 - 'allocWithZone' should be treated as following the Cocoa naming +// conventions with respect to 'return'ing ownership. +@interface PR3677: NSObject @end +@implementation PR3677 ++ (id)allocWithZone:(NSZone *)inZone { + return [super allocWithZone:inZone]; // no-warning +} +@end + +// PR 3820 - Reason about calls to -dealloc +void pr3820_DeallocInsteadOfRelease(void) +{ + id foo = [[NSString alloc] init]; // no-warning + [foo dealloc]; + // foo is not leaked, since it has been deallocated. +} + +void pr3820_ReleaseAfterDealloc(void) +{ + id foo = [[NSString alloc] init]; + [foo dealloc]; + [foo release]; // expected-warning{{used after it is release}} + // NSInternalInconsistencyException: message sent to deallocated object +} + +void pr3820_DeallocAfterRelease(void) +{ + NSLog(@"\n\n[%s]", __FUNCTION__); + id foo = [[NSString alloc] init]; + [foo release]; + [foo dealloc]; // expected-warning{{used after it is released}} + // message sent to released object +} + +// From <rdar://problem/6704930>. The problem here is that 'length' binds to +// '($0 - 1)' after '--length', but SimpleConstraintManager doesn't know how to +// reason about '($0 - 1) > constant'. As a temporary hack, we drop the value +// of '($0 - 1)' and conjure a new symbol. +void rdar6704930(unsigned char *s, unsigned int length) { + NSString* name = 0; + if (s != 0) { + if (length > 0) { + while (length > 0) { + if (*s == ':') { + ++s; + --length; + name = [[NSString alloc] init]; // no-warning + break; + } + ++s; + --length; + } + if ((length == 0) && (name != 0)) { + [name release]; + name = 0; + } + if (length == 0) { // no ':' found -> use it all as name + name = [[NSString alloc] init]; // no-warning + } + } + } + + if (name != 0) { + [name release]; + } +} + +//===----------------------------------------------------------------------===// +// <rdar://problem/6833332> +// One build of the analyzer accidentally stopped tracking the allocated +// object after the 'retain'. +//===----------------------------------------------------------------------===// + +@interface rdar_6833332 : NSObject <NSApplicationDelegate> { + NSWindow *window; +} +@property (nonatomic, retain) NSWindow *window; +@end + +@implementation rdar_6833332 +@synthesize window; +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + NSMutableDictionary *dict = [[NSMutableDictionary dictionaryWithCapacity:4] retain]; // expected-warning{{leak}} + + [dict setObject:@"foo" forKey:@"bar"]; + + NSLog(@"%@", dict); +} +- (void)dealloc { + [window release]; + [super dealloc]; +} + +- (void)radar10102244 { + NSMutableDictionary *dict = [[NSMutableDictionary dictionaryWithCapacity:4] retain]; // expected-warning{{leak}} + if (window) + NSLog(@"%@", window); +} +@end + +//===----------------------------------------------------------------------===// +// <rdar://problem/6257780> clang checker fails to catch use-after-release +//===----------------------------------------------------------------------===// + +int rdar_6257780_Case1() { + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + NSArray *array = [NSArray array]; + [array release]; // expected-warning{{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} + [pool drain]; + return 0; +} + +//===----------------------------------------------------------------------===// +// <rdar://problem/10640253> Analyzer is confused about NSAutoreleasePool -allocWithZone:. +//===----------------------------------------------------------------------===// + +void rdar_10640253_autorelease_allocWithZone() { + NSAutoreleasePool *pool = [[NSAutoreleasePool allocWithZone:(NSZone*)0] init]; + (void) pool; +} + +//===----------------------------------------------------------------------===// +// <rdar://problem/6866843> Checker should understand new/setObject:/release constructs +//===----------------------------------------------------------------------===// + +void rdar_6866843() { + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + NSMutableDictionary* dictionary = [[NSMutableDictionary alloc] init]; + NSArray* array = [[NSArray alloc] init]; + [dictionary setObject:array forKey:@"key"]; + [array release]; + // Using 'array' here should be fine + NSLog(@"array = %@\n", array); // no-warning + // Now the array is released + [dictionary release]; + [pool drain]; +} + + +//===----------------------------------------------------------------------===// +// <rdar://problem/6877235> Classes typedef-ed to CF objects should get the same treatment as CF objects +//===----------------------------------------------------------------------===// + +typedef CFTypeRef OtherRef; + +@interface RDar6877235 : NSObject {} +- (CFTypeRef)_copyCFTypeRef CF_RETURNS_RETAINED; +- (OtherRef)_copyOtherRef CF_RETURNS_RETAINED; +@end + +@implementation RDar6877235 +- (CFTypeRef)_copyCFTypeRef { + return [[NSString alloc] init]; // no-warning +} +- (OtherRef)_copyOtherRef { + return [[NSString alloc] init]; // no-warning +} +@end + +//===----------------------------------------------------------------------===// +// <rdar://problem/6320065> false positive - init method returns an object +// owned by caller +//===----------------------------------------------------------------------===// + +@interface RDar6320065 : NSObject { + NSString *_foo; +} +- (instancetype)initReturningNewClass; +- (id)_initReturningNewClassBad; +- (instancetype)initReturningNewClassBad2; +@end + +@interface RDar6320065Subclass : RDar6320065 +@end + +@implementation RDar6320065 +- (instancetype)initReturningNewClass { + [self release]; + self = [[RDar6320065Subclass alloc] init]; // no-warning + return self; +} +- (id)_initReturningNewClassBad { + [self release]; + [[RDar6320065Subclass alloc] init]; // expected-warning {{leak}} + return self; +} +- (instancetype)initReturningNewClassBad2 { + [self release]; + self = [[RDar6320065Subclass alloc] init]; + return [self autorelease]; // expected-warning{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} +} + +@end + +@implementation RDar6320065Subclass +@end + +int RDar6320065_test() { + RDar6320065 *test = [[RDar6320065 alloc] init]; // no-warning + [test release]; + return 0; +} + +//===----------------------------------------------------------------------===// +// <rdar://problem/7129086> -awakeAfterUsingCoder: returns an owned object +// and claims the receiver +//===----------------------------------------------------------------------===// + +@interface RDar7129086 : NSObject {} @end +@implementation RDar7129086 +- (id)awakeAfterUsingCoder:(NSCoder *)aDecoder { + [self release]; // no-warning + return [NSString alloc]; // no-warning +} +@end + +//===----------------------------------------------------------------------===// +// <rdar://problem/6859457> [NSData dataWithBytesNoCopy] does not return a +// retained object +//===----------------------------------------------------------------------===// + +@interface RDar6859457 : NSObject {} +- (NSString*) NoCopyString; +- (NSString*) noCopyString; +@end + +@implementation RDar6859457 +- (NSString*) NoCopyString { return [[NSString alloc] init]; } // expected-warning{{leak}} +- (NSString*) noCopyString { return [[NSString alloc] init]; } // expected-warning{{leak}} +@end + +void test_RDar6859457(RDar6859457 *x, void *bytes, NSUInteger dataLength) { + [x NoCopyString]; // expected-warning{{leak}} + [x noCopyString]; // expected-warning{{leak}} + [NSData dataWithBytesNoCopy:bytes length:dataLength]; // no-warning + [NSData dataWithBytesNoCopy:bytes length:dataLength freeWhenDone:1]; // no-warning +} + +//===----------------------------------------------------------------------===// +// PR 4230 - an autorelease pool is not necessarily leaked during a premature +// return +//===----------------------------------------------------------------------===// + +static void PR4230(void) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // no-warning + NSString *object = [[[NSString alloc] init] autorelease]; // no-warning + return; +} + +static void PR4230_new(void) +{ + NSAutoreleasePool *pool = [NSAutoreleasePool new]; // no-warning + NSString *object = [[[NSString alloc] init] autorelease]; // no-warning + return; +} + +//===----------------------------------------------------------------------===// +// Method name that has a null IdentifierInfo* for its first selector slot. +// This test just makes sure that we handle it. +//===----------------------------------------------------------------------===// + +@interface TestNullIdentifier +@end + +@implementation TestNullIdentifier ++ (id):(int)x, ... { + return [[NSString alloc] init]; // expected-warning{{leak}} +} +@end + +//===----------------------------------------------------------------------===// +// <rdar://problem/6893565> don't flag leaks for return types that cannot be +// determined to be CF types +//===----------------------------------------------------------------------===// + +// We don't know if 'struct s6893565' represents a Core Foundation type, so +// we shouldn't emit an error here. +typedef struct s6893565* TD6893565; + +@interface RDar6893565 {} +-(TD6893565)newThing; +@end + +@implementation RDar6893565 +-(TD6893565)newThing { + return (TD6893565) [[NSString alloc] init]; // no-warning +} +@end + +//===----------------------------------------------------------------------===// +// <rdar://problem/6902710> clang: false positives w/QC and CoreImage methods +//===----------------------------------------------------------------------===// + +void rdar6902710(QCView *view, QCRenderer *renderer, CIContext *context, + NSString *str, CIImage *img, CGRect rect, + CIFormat form, CGColorSpaceRef cs) { + [view createSnapshotImageOfType:str]; // expected-warning{{leak}} + [renderer createSnapshotImageOfType:str]; // expected-warning{{leak}} + [context createCGImage:img fromRect:rect]; // expected-warning{{leak}} + [context createCGImage:img fromRect:rect format:form colorSpace:cs]; // expected-warning{{leak}} +} + +//===----------------------------------------------------------------------===// +// <rdar://problem/6945561> -[CIContext createCGLayerWithSize:info:] +// misinterpreted by clang scan-build +//===----------------------------------------------------------------------===// + +void rdar6945561(CIContext *context, CGSize size, CFDictionaryRef d) { + [context createCGLayerWithSize:size info:d]; // expected-warning{{leak}} +} + +//===----------------------------------------------------------------------===// +// <rdar://problem/6961230> add knowledge of IOKit functions to retain/release +// checker +//===----------------------------------------------------------------------===// + +void IOBSDNameMatching_wrapper(mach_port_t masterPort, uint32_t options, const char * bsdName) { + IOBSDNameMatching(masterPort, options, bsdName); // expected-warning{{leak}} +} + +void IOServiceMatching_wrapper(const char * name) { + IOServiceMatching(name); // expected-warning{{leak}} +} + +void IOServiceNameMatching_wrapper(const char * name) { + IOServiceNameMatching(name); // expected-warning{{leak}} +} + +CF_RETURNS_RETAINED CFDictionaryRef CreateDict(); + +void IOServiceAddNotification_wrapper(mach_port_t masterPort, const io_name_t notificationType, + mach_port_t wakePort, uintptr_t reference, io_iterator_t * notification ) { + + CFDictionaryRef matching = CreateDict(); + CFRelease(matching); + IOServiceAddNotification(masterPort, notificationType, matching, // expected-warning{{used after it is released}} expected-warning{{deprecated}} + wakePort, reference, notification); +} + +void IORegistryEntryIDMatching_wrapper(uint64_t entryID ) { + IORegistryEntryIDMatching(entryID); // expected-warning{{leak}} +} + +void IOOpenFirmwarePathMatching_wrapper(mach_port_t masterPort, uint32_t options, + const char * path) { + IOOpenFirmwarePathMatching(masterPort, options, path); // expected-warning{{leak}} +} + +void IOServiceGetMatchingService_wrapper(mach_port_t masterPort) { + CFDictionaryRef matching = CreateDict(); + IOServiceGetMatchingService(masterPort, matching); + CFRelease(matching); // expected-warning{{used after it is released}} +} + +void IOServiceGetMatchingServices_wrapper(mach_port_t masterPort, io_iterator_t *existing) { + CFDictionaryRef matching = CreateDict(); + IOServiceGetMatchingServices(masterPort, matching, existing); + CFRelease(matching); // expected-warning{{used after it is released}} +} + +void IOServiceAddMatchingNotification_wrapper(IONotificationPortRef notifyPort, const io_name_t notificationType, + IOServiceMatchingCallback callback, void * refCon, io_iterator_t * notification) { + + CFDictionaryRef matching = CreateDict(); + IOServiceAddMatchingNotification(notifyPort, notificationType, matching, callback, refCon, notification); + CFRelease(matching); // expected-warning{{used after it is released}} +} + +//===----------------------------------------------------------------------===// +// Test of handling objects whose references "escape" to containers. +//===----------------------------------------------------------------------===// + +void CFDictionaryAddValue(CFMutableDictionaryRef, void *, void *); + +// <rdar://problem/6539791> +void rdar_6539791(CFMutableDictionaryRef y, void* key, void* val_key) { + CFMutableDictionaryRef x = CFDictionaryCreateMutable(kCFAllocatorDefault, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFDictionaryAddValue(y, key, x); + CFRelease(x); // the dictionary keeps a reference, so the object isn't deallocated yet + signed z = 1; + CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); + if (value) { + CFDictionaryAddValue(x, val_key, (void*)value); // no-warning + CFRelease(value); + CFDictionaryAddValue(y, val_key, (void*)value); // no-warning + } +} + +// <rdar://problem/6560661> +// Same issue, except with "AppendValue" functions. +void rdar_6560661(CFMutableArrayRef x) { + signed z = 1; + CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); + // CFArrayAppendValue keeps a reference to value. + CFArrayAppendValue(x, value); + CFRelease(value); + CFRetain(value); + CFRelease(value); // no-warning +} + +// <rdar://problem/7152619> +// Same issue, excwept with "CFAttributeStringSetAttribute". +void rdar_7152619(CFStringRef str) { + CFAttributedStringRef string = CFAttributedStringCreate(kCFAllocatorDefault, str, 0); + CFMutableAttributedStringRef attrString = CFAttributedStringCreateMutableCopy(kCFAllocatorDefault, 100, string); + CFRelease(string); + NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}} + CFAttributedStringSetAttribute(attrString, CFRangeMake(0, 1), str, number); + [number release]; + [number retain]; + CFRelease(attrString); +} + +//===----------------------------------------------------------------------===// +// Test of handling CGGradientXXX functions. +//===----------------------------------------------------------------------===// + +void rdar_7184450(CGContextRef myContext, CGFloat x, CGPoint myStartPoint, + CGPoint myEndPoint) { + size_t num_locations = 6; + CGFloat locations[6] = { 0.0, 0.265, 0.28, 0.31, 0.36, 1.0 }; + CGFloat components[28] = { 239.0/256.0, 167.0/256.0, 170.0/256.0, + x, // Start color + 207.0/255.0, 39.0/255.0, 39.0/255.0, x, + 147.0/255.0, 21.0/255.0, 22.0/255.0, x, + 175.0/255.0, 175.0/255.0, 175.0/255.0, x, + 255.0/255.0,255.0/255.0, 255.0/255.0, x, + 255.0/255.0,255.0/255.0, 255.0/255.0, x + }; // End color + + CGGradientRef myGradient = + CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), // expected-warning{{leak}} + components, locations, num_locations); + + CGContextDrawLinearGradient(myContext, myGradient, myStartPoint, myEndPoint, + 0); + CGGradientRelease(myGradient); +} + +void rdar_7184450_pos(CGContextRef myContext, CGFloat x, CGPoint myStartPoint, + CGPoint myEndPoint) { + size_t num_locations = 6; + CGFloat locations[6] = { 0.0, 0.265, 0.28, 0.31, 0.36, 1.0 }; + CGFloat components[28] = { 239.0/256.0, 167.0/256.0, 170.0/256.0, + x, // Start color + 207.0/255.0, 39.0/255.0, 39.0/255.0, x, + 147.0/255.0, 21.0/255.0, 22.0/255.0, x, + 175.0/255.0, 175.0/255.0, 175.0/255.0, x, + 255.0/255.0,255.0/255.0, 255.0/255.0, x, + 255.0/255.0,255.0/255.0, 255.0/255.0, x + }; // End color + + CGGradientRef myGradient = + CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), components, locations, num_locations); // expected-warning 2 {{leak}} + + CGContextDrawLinearGradient(myContext, myGradient, myStartPoint, myEndPoint, + 0); +} + +//===----------------------------------------------------------------------===// +// <rdar://problem/7299394> clang false positive: retained instance passed to +// thread in pthread_create marked as leak +// +// Until we have full IPA, the analyzer should stop tracking the reference +// count of objects passed to pthread_create. +// +//===----------------------------------------------------------------------===// + +struct _opaque_pthread_t {}; +struct _opaque_pthread_attr_t {}; +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; +} +void rdar_7299394(pthread_attr_t *attr, pthread_t *thread, void *args) { + NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning + pthread_create(thread, attr, rdar_7299394_start_routine, number); +} +void rdar_7299394_positive(pthread_attr_t *attr, pthread_t *thread) { + NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}} +} + +//===----------------------------------------------------------------------===// +// <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 () +// +// According to the Core Video Reference (ADC), CVPixelBufferCreateWithBytes and +// CVPixelBufferCreateWithPlanarBytes can release (via a callback) the +// pixel buffer object. These test cases show how the analyzer stops tracking +// the reference count for the objects passed for this argument. This +// could be made smarter. +//===----------------------------------------------------------------------===// + +typedef int int32_t; +typedef UInt32 FourCharCode; +typedef FourCharCode OSType; +typedef uint64_t CVOptionFlags; +typedef int32_t CVReturn; +typedef struct __CVBuffer *CVBufferRef; +typedef CVBufferRef CVImageBufferRef; +typedef CVImageBufferRef CVPixelBufferRef; +typedef void (*CVPixelBufferReleaseBytesCallback)( void *releaseRefCon, const void *baseAddress ); + +extern CVReturn CVPixelBufferCreateWithBytes(CFAllocatorRef allocator, + size_t width, + size_t height, + OSType pixelFormatType, + void *baseAddress, + size_t bytesPerRow, + CVPixelBufferReleaseBytesCallback releaseCallback, + void *releaseRefCon, + CFDictionaryRef pixelBufferAttributes, + CVPixelBufferRef *pixelBufferOut) ; + +typedef void (*CVPixelBufferReleasePlanarBytesCallback)( void *releaseRefCon, const void *dataPtr, size_t dataSize, size_t numberOfPlanes, const void *planeAddresses[] ); + +extern CVReturn CVPixelBufferCreateWithPlanarBytes(CFAllocatorRef allocator, + size_t width, + size_t height, + OSType pixelFormatType, + void *dataPtr, + size_t dataSize, + size_t numberOfPlanes, + void *planeBaseAddress[], + size_t planeWidth[], + size_t planeHeight[], + size_t planeBytesPerRow[], + CVPixelBufferReleasePlanarBytesCallback releaseCallback, + void *releaseRefCon, + CFDictionaryRef pixelBufferAttributes, + CVPixelBufferRef *pixelBufferOut) ; + +extern CVReturn CVPixelBufferCreateWithBytes(CFAllocatorRef allocator, + size_t width, + size_t height, + OSType pixelFormatType, + void *baseAddress, + size_t bytesPerRow, + CVPixelBufferReleaseBytesCallback releaseCallback, + void *releaseRefCon, + CFDictionaryRef pixelBufferAttributes, + CVPixelBufferRef *pixelBufferOut) ; + +CVReturn rdar_7283567(CFAllocatorRef allocator, size_t width, size_t height, + OSType pixelFormatType, void *baseAddress, + size_t bytesPerRow, + CVPixelBufferReleaseBytesCallback releaseCallback, + CFDictionaryRef pixelBufferAttributes, + CVPixelBufferRef *pixelBufferOut) { + + // For the allocated object, it doesn't really matter what type it is + // for the purpose of this test. All we want to show is that + // this is freed later by the callback. + NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning + + return CVPixelBufferCreateWithBytes(allocator, width, height, pixelFormatType, + baseAddress, bytesPerRow, releaseCallback, + number, // potentially released by callback + pixelBufferAttributes, pixelBufferOut) ; +} + +CVReturn rdar_7283567_2(CFAllocatorRef allocator, size_t width, size_t height, + OSType pixelFormatType, void *dataPtr, size_t dataSize, + size_t numberOfPlanes, void *planeBaseAddress[], + size_t planeWidth[], size_t planeHeight[], size_t planeBytesPerRow[], + CVPixelBufferReleasePlanarBytesCallback releaseCallback, + CFDictionaryRef pixelBufferAttributes, + CVPixelBufferRef *pixelBufferOut) { + + // For the allocated object, it doesn't really matter what type it is + // for the purpose of this test. All we want to show is that + // this is freed later by the callback. + NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning + + return CVPixelBufferCreateWithPlanarBytes(allocator, + width, height, pixelFormatType, dataPtr, dataSize, + numberOfPlanes, planeBaseAddress, planeWidth, + planeHeight, planeBytesPerRow, releaseCallback, + number, // potentially released by callback + pixelBufferAttributes, pixelBufferOut) ; +} + +//===----------------------------------------------------------------------===// +// <rdar://problem/7358899> False leak associated with +// CGBitmapContextCreateWithData +//===----------------------------------------------------------------------===// +typedef uint32_t CGBitmapInfo; +typedef void (*CGBitmapContextReleaseDataCallback)(void *releaseInfo, void *data); + +CGContextRef CGBitmapContextCreateWithData(void *data, + size_t width, size_t height, size_t bitsPerComponent, + size_t bytesPerRow, CGColorSpaceRef space, CGBitmapInfo bitmapInfo, + CGBitmapContextReleaseDataCallback releaseCallback, void *releaseInfo) CF_RETURNS_RETAINED; + +void rdar_7358899(void *data, + size_t width, size_t height, size_t bitsPerComponent, + size_t bytesPerRow, CGColorSpaceRef space, CGBitmapInfo bitmapInfo, + CGBitmapContextReleaseDataCallback releaseCallback) { + + // For the allocated object, it doesn't really matter what type it is + // for the purpose of this test. All we want to show is that + // this is freed later by the callback. + NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning + + CGBitmapContextCreateWithData(data, width, height, bitsPerComponent, // expected-warning{{leak}} + bytesPerRow, space, bitmapInfo, releaseCallback, number); +} + +//===----------------------------------------------------------------------===// +// <rdar://problem/7265711> allow 'new', 'copy', 'alloc', 'init' prefix to +// start before '_' when determining Cocoa fundamental rule +// +// Previously the retain/release checker just skipped prefixes before the +// first '_' entirely. Now the checker honors the prefix if it results in a +// recognizable naming convention (e.g., 'new', 'init'). +//===----------------------------------------------------------------------===// + +@interface RDar7265711 {} +- (id) new_stuff; +@end + +void rdar7265711_a(RDar7265711 *x) { + id y = [x new_stuff]; // expected-warning{{leak}} +} + +void rdar7265711_b(RDar7265711 *x) { + id y = [x new_stuff]; // no-warning + [y release]; +} + +//===----------------------------------------------------------------------===// +// <rdar://problem/7306898> clang thinks [NSCursor dragCopyCursor] returns a +// retained reference +//===----------------------------------------------------------------------===// + +@interface NSCursor : NSObject ++ (NSCursor *)dragCopyCursor; +@end + +void rdar7306898(void) { + // 'dragCopyCursor' does not follow Cocoa's fundamental rule. It is a noun, not an sentence + // implying a 'copy' of something. + NSCursor *c = [NSCursor dragCopyCursor]; // no-warning + NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}} +} + +//===----------------------------------------------------------------------===// +// <rdar://problem/7252064> sending 'release', 'retain', etc. to a Class +// directly is not likely what the user intended +//===----------------------------------------------------------------------===// + +@interface RDar7252064 : NSObject @end +void rdar7252064(void) { + [RDar7252064 release]; // expected-warning{{The 'release' message should be sent to instances of class 'RDar7252064' and not the class directly}} + [RDar7252064 retain]; // expected-warning{{The 'retain' message should be sent to instances of class 'RDar7252064' and not the class directly}} + [RDar7252064 autorelease]; // expected-warning{{The 'autorelease' message should be sent to instances of class 'RDar7252064' and not the class directly}} + [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}} +} + +//===----------------------------------------------------------------------===// +// Tests of ownership attributes. +//===----------------------------------------------------------------------===// + +typedef NSString* MyStringTy; + +@protocol FooP; + +@interface TestOwnershipAttr : NSObject +- (NSString*) returnsAnOwnedString NS_RETURNS_RETAINED; // no-warning +- (NSString*) returnsAnOwnedCFString CF_RETURNS_RETAINED; // no-warning +- (MyStringTy) returnsAnOwnedTypedString NS_RETURNS_RETAINED; // no-warning +- (NSString*) newString NS_RETURNS_NOT_RETAINED; // no-warning +- (NSString*) newString_auto NS_RETURNS_AUTORELEASED; // no-warning +- (NSString*) newStringNoAttr; +- (int) returnsAnOwnedInt NS_RETURNS_RETAINED; // expected-warning{{'ns_returns_retained' attribute only applies to methods that return an Objective-C object}} +- (id) pseudoInit NS_CONSUMES_SELF NS_RETURNS_RETAINED; ++ (void) consume:(id) NS_CONSUMED x; ++ (void) consume2:(id) CF_CONSUMED x; +@end + +static int ownership_attribute_doesnt_go_here NS_RETURNS_RETAINED; // expected-warning{{'ns_returns_retained' attribute only applies to functions and methods}} + +void test_attr_1(TestOwnershipAttr *X) { + NSString *str = [X returnsAnOwnedString]; // expected-warning{{leak}} +} + +void test_attr_1b(TestOwnershipAttr *X) { + NSString *str = [X returnsAnOwnedCFString]; // expected-warning{{leak}} +} + +void test_attr1c(TestOwnershipAttr *X) { + NSString *str = [X newString]; // no-warning + NSString *str2 = [X newStringNoAttr]; // expected-warning{{leak}} + NSString *str3 = [X newString_auto]; // no-warning + NSString *str4 = [[X newString_auto] retain]; // expected-warning {{leak}} +} + +void testattr2_a() { + TestOwnershipAttr *x = [TestOwnershipAttr alloc]; // expected-warning{{leak}} +} + +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]; +} + +void testattr3() { + TestOwnershipAttr *x = [TestOwnershipAttr alloc]; // no-warning + [TestOwnershipAttr consume:x]; + TestOwnershipAttr *y = [TestOwnershipAttr alloc]; // no-warning + [TestOwnershipAttr consume2:y]; +} + +void consume_ns(id NS_CONSUMED x); +void consume_cf(id CF_CONSUMED x); + +void testattr4() { + TestOwnershipAttr *x = [TestOwnershipAttr alloc]; // no-warning + consume_ns(x); + TestOwnershipAttr *y = [TestOwnershipAttr alloc]; // no-warning + consume_cf(y); +} + +@interface TestOwnershipAttr2 : NSObject +- (NSString*) newString NS_RETURNS_NOT_RETAINED; // no-warning +@end + +@implementation TestOwnershipAttr2 +- (NSString*) newString { + return [NSString alloc]; // expected-warning {{Potential leak of an object}} +} +@end + +@interface MyClassTestCFAttr : NSObject {} +- (NSDate*) returnsCFRetained CF_RETURNS_RETAINED; +- (CFDateRef) returnsCFRetainedAsCF CF_RETURNS_RETAINED; +- (CFDateRef) newCFRetainedAsCF CF_RETURNS_NOT_RETAINED; +- (CFDateRef) newCFRetainedAsCFNoAttr CF_RETURNS_RETAINED; +- (NSDate*) alsoReturnsRetained; +- (CFDateRef) alsoReturnsRetainedAsCF CF_RETURNS_NOT_RETAINED; +- (NSDate*) returnsNSRetained NS_RETURNS_RETAINED; +@end + +CF_RETURNS_RETAINED +CFDateRef returnsRetainedCFDate() { + return CFDateCreate(0, CFAbsoluteTimeGetCurrent()); +} + +@implementation MyClassTestCFAttr +- (NSDate*) returnsCFRetained { + return (NSDate*) returnsRetainedCFDate(); // No leak. +} + +- (CFDateRef) returnsCFRetainedAsCF { + return returnsRetainedCFDate(); // No leak. +} + +- (CFDateRef) newCFRetainedAsCF { + return (CFDateRef)[(id)[self returnsCFRetainedAsCF] autorelease]; +} + +- (CFDateRef) newCFRetainedAsCFNoAttr { + 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}} +} + +- (NSDate*) alsoReturnsRetained { + return (NSDate*) returnsRetainedCFDate(); // expected-warning{{leak}} +} + +- (CFDateRef) alsoReturnsRetainedAsCF { + return returnsRetainedCFDate(); // expected-warning{{leak}} +} + + +- (NSDate*) returnsNSRetained { + return (NSDate*) returnsRetainedCFDate(); // no-warning +} +@end + +//===----------------------------------------------------------------------===// +// Test that leaks post-dominated by "panic" functions are not reported. +// +// <rdar://problem/5905851> do not report a leak when post-dominated by a call +// to a noreturn or panic function +//===----------------------------------------------------------------------===// + +void panic() __attribute__((noreturn)); +void panic_not_in_hardcoded_list() __attribute__((noreturn)); + +void test_panic_negative() { + signed z = 1; + CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // expected-warning{{leak}} +} + +void test_panic_positive() { + signed z = 1; + CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // no-warning + panic(); +} + +void test_panic_neg_2(int x) { + signed z = 1; + CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // expected-warning{{leak}} + if (x) + panic(); +} + +void test_panic_pos_2(int x) { + signed z = 1; + CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // no-warning + if (x) + panic(); + if (!x) { + // This showed up in <rdar://problem/7796563>, where we silently missed checking + // the function type for noreturn. "panic()" is a hard-coded known panic function + // that isn't always noreturn. + panic_not_in_hardcoded_list(); + } +} + +//===----------------------------------------------------------------------===// +// Test uses of blocks (closures) +//===----------------------------------------------------------------------===// + +void test_blocks_1_pos(void) { + NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}} + ^{}(); +} + +void test_blocks_1_indirect_release(void) { + NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning + ^{ [number release]; }(); +} + +void test_blocks_1_indirect_retain(void) { + // Eventually this should be reported as a leak. + NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning + ^{ [number retain]; }(); +} + +void test_blocks_1_indirect_release_via_call(void) { + NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning + ^(NSObject *o){ [o release]; }(number); +} + +void test_blocks_1_indirect_retain_via_call(void) { + NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning {{leak}} + ^(NSObject *o){ [o retain]; }(number); +} + +//===--------------------------------------------------------------------===// +// Test sending message to super that returns an object alias. Previously +// this caused a crash in the analyzer. +//===--------------------------------------------------------------------===// + +@interface Rdar8015556 : NSObject {} @end +@implementation Rdar8015556 +- (id)retain { + return [super retain]; +} +@end + +// <rdar://problem/8272168> - Correcly handle Class<...> in Cocoa Conventions +// detector. + +@protocol Prot_R8272168 @end +Class <Prot_R8272168> GetAClassThatImplementsProt_R8272168(); +void r8272168() { + GetAClassThatImplementsProt_R8272168(); +} + +// Test case for <rdar://problem/8356342>, which in the past triggered +// a false positive. +@interface RDar8356342 +- (NSDate*) rdar8356342:(NSDate *)inValue; +@end + +@implementation RDar8356342 +- (NSDate*) rdar8356342:(NSDate*)inValue { + NSDate *outValue = inValue; + if (outValue == 0) + outValue = [[NSDate alloc] init]; // no-warning + + if (outValue != inValue) + [outValue autorelease]; + + return outValue; +} +@end + +// <rdar://problem/8724287> - This test case previously crashed because +// of a bug in BugReporter. +extern const void *CFDictionaryGetValue(CFDictionaryRef theDict, const void *key) CF_RETURNS_NOT_RETAINED; +typedef struct __CFError * CFErrorRef; +extern const CFStringRef kCFErrorUnderlyingErrorKey; +extern CFDictionaryRef CFErrorCopyUserInfo(CFErrorRef err) CF_RETURNS_RETAINED; +static void rdar_8724287(CFErrorRef error) +{ + CFErrorRef error_to_dump; + + error_to_dump = error; + while (error_to_dump != ((void*)0)) { + CFDictionaryRef info; + + info = CFErrorCopyUserInfo(error_to_dump); // expected-warning{{Potential leak of an object}} + + if (info != ((void*)0)) { + } + + error_to_dump = (CFErrorRef) CFDictionaryGetValue(info, kCFErrorUnderlyingErrorKey); + } +} + +// <rdar://problem/9234108> - Make sure the model applies cf_consumed +// correctly in argument positions besides the first. + +CF_IMPLICIT_BRIDGING_ENABLED + +extern void *CFStringCreate(void); + +CF_IMPLICIT_BRIDGING_DISABLED + +extern void rdar_9234108_helper(void *key, void * CF_CONSUMED value); +void rdar_9234108() { + rdar_9234108_helper(0, CFStringCreate()); +} + +// <rdar://problem/9726279> - Make sure that objc_method_family works +// to override naming conventions. +struct TwoDoubles { + double one; + double two; +}; +typedef struct TwoDoubles TwoDoubles; + +@interface NSValue (Mine) +- (id)_prefix_initWithTwoDoubles:(TwoDoubles)twoDoubles __attribute__((objc_method_family(init))); +@end + +@implementation NSValue (Mine) +- (id)_prefix_initWithTwoDoubles:(TwoDoubles)twoDoubles +{ + return [self init]; +} +@end + +void rdar9726279() { + TwoDoubles twoDoubles = { 0.0, 0.0 }; + NSValue *value = [[NSValue alloc] _prefix_initWithTwoDoubles:twoDoubles]; + [value release]; +} + +// <rdar://problem/9732321> +// Test camelcase support for CF conventions. While Core Foundation APIs +// don't use camel casing, other code is allowed to use it. +CFArrayRef camelcase_create_1() { + return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning +} + +CFArrayRef camelcase_createno() { + return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning {{leak}} +} + +CFArrayRef camelcase_copy() { + return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning +} + +CFArrayRef camelcase_copying() { + return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning {{leak}} +} + +CFArrayRef copyCamelCase() { + return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning +} + +CFArrayRef __copyCamelCase() { + return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning +} + +CFArrayRef __createCamelCase() { + return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning +} + +CFArrayRef camel_create() { + return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning +} + + +CFArrayRef camel_creat() { + return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning {{leak}} +} + +CFArrayRef camel_copy() { + return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning +} + +CFArrayRef camel_copyMachine() { + return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning +} + +CFArrayRef camel_copymachine() { + return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning {{leak}} +} + +// rdar://problem/8024350 +@protocol F18P +- (id) clone; +@end +@interface F18 : NSObject<F18P> @end +@interface F18(Cat) +- (id) clone NS_RETURNS_RETAINED; +@end + +@implementation F18 +- (id) clone { + return [F18 alloc]; +} +@end + +// Radar 6582778. +void rdar6582778(void) { + CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); + CFTypeRef vals[] = { CFDateCreate(0, t) }; // expected-warning {{leak}} +} + +CFTypeRef global; + +void rdar6582778_2(void) { + CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); + global = CFDateCreate(0, t); // no-warning +} + +// <rdar://problem/10232019> - Test that objects passed to containers +// are marked "escaped". + +void rdar10232019() { + NSMutableArray *array = [NSMutableArray array]; + + NSString *string = [[NSString alloc] initWithUTF8String:"foo"]; + [array addObject:string]; + [string release]; + + NSString *otherString = [string stringByAppendingString:@"bar"]; // no-warning + NSLog(@"%@", otherString); +} + +void rdar10232019_positive() { + NSMutableArray *array = [NSMutableArray array]; + + NSString *string = [[NSString alloc] initWithUTF8String:"foo"]; + [string release]; + + NSString *otherString = [string stringByAppendingString:@"bar"]; // expected-warning {{Reference-counted object is used after it is release}} + NSLog(@"%@", otherString); +} + +// RetainCountChecker support for XPC. +// <rdar://problem/9658496> +typedef void * xpc_object_t; +xpc_object_t _CFXPCCreateXPCObjectFromCFObject(CFTypeRef cf); +void xpc_release(xpc_object_t object); + +void rdar9658496() { + CFStringRef cf; + xpc_object_t xpc; + cf = CFStringCreateWithCString( ((CFAllocatorRef)0), "test", kCFStringEncodingUTF8 ); // no-warning + xpc = _CFXPCCreateXPCObjectFromCFObject( cf ); + CFRelease(cf); + xpc_release(xpc); +} + +// Support annotations with method families. +@interface RDar10824732 : NSObject +- (instancetype)initWithObj:(id CF_CONSUMED)obj; +@end + +@implementation RDar10824732 +- (instancetype)initWithObj:(id)obj { + [obj release]; + return [super init]; +} +@end + +void rdar_10824732() { + @autoreleasepool { + NSString *obj = @"test"; + RDar10824732 *foo = [[RDar10824732 alloc] initWithObj:obj]; // no-warning + [foo release]; + } +} + +// 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]; +} + +- (id)copyAutoreleaseRadar13081402 { + id x = [[[NSString alloc] initWithUTF8String:"foo"] autorelease]; + [x retain]; + return x; // no warning +} + +@end +//===----------------------------------------------------------------------===// +// Test returning allocated memory in a struct. +// +// We currently don't have a general way to track pointers that "escape". +// Here we test that RetainCountChecker doesn't get excited about returning +// allocated CF objects in struct fields. +//===----------------------------------------------------------------------===// +void *malloc(size_t); +struct rdar11104566 { CFStringRef myStr; }; +struct rdar11104566 test_rdar11104566() { + CFStringRef cf = CFStringCreateWithCString( ((CFAllocatorRef)0), "test", kCFStringEncodingUTF8 ); // no-warning + struct rdar11104566 V; + V.myStr = cf; + return V; // no-warning +} + +struct rdar11104566 *test_2_rdar11104566() { + CFStringRef cf = CFStringCreateWithCString( ((CFAllocatorRef)0), "test", kCFStringEncodingUTF8 ); // no-warning + struct rdar11104566 *V = (struct rdar11104566 *) malloc(sizeof(*V)); + V->myStr = cf; + return V; // no-warning +} + +//===----------------------------------------------------------------------===// +// ObjC literals support. +//===----------------------------------------------------------------------===// + +void test_objc_arrays() { + { // CASE ONE -- OBJECT IN ARRAY CREATED DIRECTLY + NSObject *o = [[NSObject alloc] init]; + NSArray *a = [[NSArray alloc] initWithObjects:o, (void*)0]; // expected-warning {{leak}} + [o release]; + [a description]; + [o description]; + } + + { // CASE TWO -- OBJECT IN ARRAY CREATED BY DUPING AUTORELEASED ARRAY + NSObject *o = [[NSObject alloc] init]; + NSArray *a1 = [NSArray arrayWithObjects:o, (void*)0]; + NSArray *a2 = [[NSArray alloc] initWithArray:a1]; // expected-warning {{leak}} + [o release]; + [a2 description]; + [o description]; + } + + { // CASE THREE -- OBJECT IN RETAINED @[] + NSObject *o = [[NSObject alloc] init]; + NSArray *a3 = [@[o] retain]; // expected-warning {{leak}} + [o release]; + [a3 description]; + [o description]; + } + + { // CASE FOUR -- OBJECT IN ARRAY CREATED BY DUPING @[] + NSObject *o = [[NSObject alloc] init]; + NSArray *a = [[NSArray alloc] initWithArray:@[o]]; // expected-warning {{leak}} + [o release]; + + [a description]; + [o description]; + } + + { // CASE FIVE -- OBJECT IN RETAINED @{} + NSValue *o = [[NSValue alloc] init]; + NSDictionary *a = [@{o : o} retain]; // expected-warning {{leak}} + [o release]; + + [a description]; + [o description]; + } +} + +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 +} + + +void consumeAndStopTracking(id NS_CONSUMED obj, void (^callback)(void)); +void CFConsumeAndStopTracking(CFTypeRef CF_CONSUMED obj, void (^callback)(void)); + +void testConsumeAndStopTracking() { + id retained = [@[] retain]; // +1 + consumeAndStopTracking(retained, ^{}); // no-warning + + id doubleRetained = [[@[] retain] retain]; // +2 + consumeAndStopTracking(doubleRetained, ^{ + [doubleRetained release]; + }); // no-warning + + id unretained = @[]; // +0 + consumeAndStopTracking(unretained, ^{}); // expected-warning {{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} +} + +void testCFConsumeAndStopTracking() { + id retained = [@[] retain]; // +1 + CFConsumeAndStopTracking((CFTypeRef)retained, ^{}); // no-warning + + id doubleRetained = [[@[] retain] retain]; // +2 + CFConsumeAndStopTracking((CFTypeRef)doubleRetained, ^{ + [doubleRetained release]; + }); // no-warning + + id unretained = @[]; // +0 + CFConsumeAndStopTracking((CFTypeRef)unretained, ^{}); // expected-warning {{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} +} +//===----------------------------------------------------------------------===// +// Test 'pragma clang arc_cf_code_audited' support. +//===----------------------------------------------------------------------===// + +typedef void *MyCFType; +#pragma clang arc_cf_code_audited begin +MyCFType CreateMyCFType(); +#pragma clang arc_cf_code_audited end + +void test_custom_cf() { + MyCFType x = CreateMyCFType(); // expected-warning {{leak of an object stored into 'x'}} +} + +//===----------------------------------------------------------------------===// +// Test calling CFPlugInInstanceCreate, which appears in CF but doesn't +// return a CF object. +//===----------------------------------------------------------------------===// + +void test_CFPlugInInstanceCreate(CFUUIDRef factoryUUID, CFUUIDRef typeUUID) { + CFPlugInInstanceCreate(kCFAllocatorDefault, factoryUUID, typeUUID); // no-warning +} + +//===----------------------------------------------------------------------===// +// PR14927: -drain only has retain-count semantics on NSAutoreleasePool. +//===----------------------------------------------------------------------===// + +@interface PR14927 : NSObject +- (void)drain; +@end + +void test_drain() { + PR14927 *obj = [[PR14927 alloc] init]; + [obj drain]; + [obj release]; // no-warning +} + +//===----------------------------------------------------------------------===// +// Allow cf_returns_retained and cf_returns_not_retained to mark a return +// value as tracked, even if the object isn't a known CF type. +//===----------------------------------------------------------------------===// + +MyCFType getCustom() __attribute__((cf_returns_not_retained)); +MyCFType makeCustom() __attribute__((cf_returns_retained)); + +void testCustomReturnsRetained() { + MyCFType obj = makeCustom(); // expected-warning {{leak of an object stored into 'obj'}} +} + +void testCustomReturnsNotRetained() { + CFRelease(getCustom()); // expected-warning {{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} +} + +//===----------------------------------------------------------------------===// +// Don't print variables which are out of the current scope. +//===----------------------------------------------------------------------===// +@interface MyObj12706177 : NSObject +-(instancetype)initX; ++(void)test12706177; +@end +static int Cond; +@implementation MyObj12706177 +-(instancetype)initX { + if (Cond) + return 0; + self = [super init]; + return self; +} ++(void)test12706177 { + id x = [[MyObj12706177 alloc] initX]; //expected-warning {{Potential leak of an object}} + [x release]; +} +@end + +//===----------------------------------------------------------------------===// +// <rdar://problem/13783514> xpc_connection_set_finalizer_f +//===----------------------------------------------------------------------===// + +typedef xpc_object_t xpc_connection_t; +typedef void (*xpc_finalizer_t)(void *value); +void xpc_connection_set_context(xpc_connection_t connection, void *ctx); +void xpc_connection_set_finalizer_f(xpc_connection_t connection, + xpc_finalizer_t finalizer); +void releaseAfterXPC(void *context) { + [(NSArray *)context release]; +} + +void rdar13783514(xpc_connection_t connection) { + xpc_connection_set_context(connection, [[NSMutableArray alloc] init]); + xpc_connection_set_finalizer_f(connection, releaseAfterXPC); +} // no-warning + +CFAttributedStringRef CFAttributedCreate(void *CFObj CF_CONSUMED) CF_RETURNS_RETAINED; + +@interface Action +@property (nonatomic) SEL action; +@property (nonatomic, assign) id target; +@end diff --git a/test/ARCMT/objcmt-atomic-property.m b/test/ARCMT/objcmt-atomic-property.m new file mode 100644 index 0000000..78ab3ec --- /dev/null +++ b/test/ARCMT/objcmt-atomic-property.m @@ -0,0 +1,229 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fblocks -objcmt-migrate-readwrite-property -objcmt-migrate-readonly-property -objcmt-atomic-property -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 +// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result +// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result + +#define WEBKIT_OBJC_METHOD_ANNOTATION(ANNOTATION) ANNOTATION +#define WEAK_IMPORT_ATTRIBUTE __attribute__((objc_arc_weak_reference_unavailable)) +#define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER +#define DEPRECATED __attribute__((deprecated)) + +typedef char BOOL; +@class NSString; +@protocol NSCopying @end + +@interface NSObject <NSCopying> +@end + +@interface NSDictionary : NSObject +@end + +@interface I : NSObject { + int ivarVal; +} +- (void) setWeakProp : (NSString *__weak)Val; +- (NSString *__weak) WeakProp; + +- (NSString *) StrongProp; +- (void) setStrongProp : (NSString *)Val; + +- (NSString *) UnavailProp __attribute__((unavailable)); +- (void) setUnavailProp : (NSString *)Val; + +- (NSString *) UnavailProp1 __attribute__((unavailable)); +- (void) setUnavailProp1 : (NSString *)Val __attribute__((unavailable)); + +- (NSString *) UnavailProp2; +- (void) setUnavailProp2 : (NSString *)Val __attribute__((unavailable)); + +- (NSDictionary*) undoAction; +- (void) setUndoAction: (NSDictionary*)Arg; +@end + +@implementation I +@end + +@class NSArray; + +@interface MyClass2 { +@private + NSArray *_names1; + NSArray *_names2; + NSArray *_names3; + NSArray *_names4; +} +- (void)setNames1:(NSArray *)names; +- (void)setNames4:(__strong NSArray *)names; +- (void)setNames3:(__strong NSArray *)names; +- (void)setNames2:(NSArray *)names; +- (NSArray *) names2; +- (NSArray *)names3; +- (__strong NSArray *)names4; +- (NSArray *) names1; +@end + +// Properties that contain the name "delegate" or "dataSource", +// or have exact name "target" have unsafe_unretained attribute. +@interface NSInvocation +- (id)target; +- (void)setTarget:(id)target; + +- (id) dataSource; + +- (id)xxxdelegateYYY; +- (void)setXxxdelegateYYY:(id)delegate; + +- (void)setDataSource:(id)source; + +- (id)MYtarget; +- (void)setMYtarget: (id)target; + +- (id)targetX; +- (void)setTargetX: (id)t; + +- (int)value; +- (void)setValue: (int)val; + +-(BOOL) isContinuous; +-(void) setContinuous:(BOOL)value; + +- (id) isAnObject; +- (void)setAnObject : (id) object; + +- (BOOL) isinValid; +- (void) setInValid : (BOOL) arg; + +- (void) Nothing; +- (int) Length; +- (id) object; ++ (double) D; +- (void *)JSObject WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER); +- (BOOL)isIgnoringInteractionEvents; + +- (NSString *)getStringValue; +- (BOOL)getCounterValue; +- (void)setStringValue:(NSString *)stringValue AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +- (NSDictionary *)getns_dixtionary; + +- (BOOL)is3bar; // watch out +- (NSString *)get3foo; // watch out + +- (BOOL) getM; +- (BOOL) getMA; +- (BOOL) getALL; +- (BOOL) getMANY; +- (BOOL) getSome; +@end + + +@interface NSInvocation(CAT) +- (id)target; +- (void)setTarget:(id)target; + +- (id) dataSource; + +- (id)xxxdelegateYYY; +- (void)setXxxdelegateYYY:(id)delegate; + +- (void)setDataSource:(id)source; + +- (id)MYtarget; +- (void)setMYtarget: (id)target; + +- (id)targetX; +- (void)setTargetX: (id)t; + +- (int)value; +- (void)setValue: (int)val; + +-(BOOL) isContinuous; +-(void) setContinuous:(BOOL)value; + +- (id) isAnObject; +- (void)setAnObject : (id) object; + +- (BOOL) isinValid; +- (void) setInValid : (BOOL) arg; + +- (void) Nothing; +- (int) Length; +- (id) object; ++ (double) D; + +- (BOOL)is3bar; // watch out +- (NSString *)get3foo; // watch out + +- (BOOL) getM; +- (BOOL) getMA; +- (BOOL) getALL; +- (BOOL) getMANY; +- (BOOL) getSome; +@end + +DEPRECATED +@interface I_DEP +- (BOOL) isinValid; +- (void) setInValid : (BOOL) arg; +@end + +@interface AnotherOne +- (BOOL) isinValid DEPRECATED; +- (void) setInValid : (BOOL) arg; +- (id)MYtarget; +- (void)setMYtarget: (id)target DEPRECATED; +- (BOOL) getM DEPRECATED; + +- (id)xxxdelegateYYY DEPRECATED; +- (void)setXxxdelegateYYY:(id)delegate DEPRECATED; +@end + +// rdar://14987909 +#define NS_AVAILABLE __attribute__((availability(macosx,introduced=10.0))) +#define NORETURN __attribute__((noreturn)) +#define ALIGNED __attribute__((aligned(16))) + +@interface NSURL +// Do not infer a property. +- (NSURL *)appStoreReceiptURL NS_AVAILABLE; +- (void) setAppStoreReceiptURL : (NSURL *)object; + +- (NSURL *)appStoreReceiptURLX NS_AVAILABLE; +- (void) setAppStoreReceiptURLX : (NSURL *)object NS_AVAILABLE; + +// Do not infer a property. +- (NSURL *)appStoreReceiptURLY ; +- (void) setAppStoreReceiptURLY : (NSURL *)object NS_AVAILABLE; + +- (id)OkToInfer NS_AVAILABLE; + +// Do not infer a property. +- (NSURL *)appStoreReceiptURLZ ; +- (void) setAppStoreReceiptURLZ : (NSURL *)object NS_AVAILABLE; + +// Do not infer a property. +- (id) t1 NORETURN NS_AVAILABLE; +- (void) setT1 : (id) arg NS_AVAILABLE; + +- (id)method1 ALIGNED NS_AVAILABLE; +- (void) setMethod1 : (id) object NS_AVAILABLE ALIGNED; + +- (NSURL *)init; // No Change ++ (id)alloc; // No Change + +- (BOOL)is1stClass; // Not a valid property +- (BOOL)isClass; // This is a valid property 'class' is not a keyword in ObjC +- (BOOL)isDouble; // Not a valid property + +@end + +// rdar://15082818 +@class NSMutableDictionary; + +@interface NSArray +- (id (^)(id, NSArray *, NSMutableDictionary *)) expressionBlock; +- (id (^)(id, NSArray *, NSMutableDictionary *)) MyBlock; +- (void) setMyBlock : (id (^)(id, NSArray *, NSMutableDictionary *)) bl; +- (id (*)(id, NSArray *, NSMutableDictionary *)) expressionFuncptr; +- (id (*)(id, NSArray *, NSMutableDictionary *)) MyFuncptr; +- (void) setMyFuncptr : (id (*)(id, NSArray *, NSMutableDictionary *)) bl; +@end diff --git a/test/ARCMT/objcmt-atomic-property.m.result b/test/ARCMT/objcmt-atomic-property.m.result new file mode 100644 index 0000000..1650cd2 --- /dev/null +++ b/test/ARCMT/objcmt-atomic-property.m.result @@ -0,0 +1,202 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fblocks -objcmt-migrate-readwrite-property -objcmt-migrate-readonly-property -objcmt-atomic-property -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 +// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result +// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result + +#define WEBKIT_OBJC_METHOD_ANNOTATION(ANNOTATION) ANNOTATION +#define WEAK_IMPORT_ATTRIBUTE __attribute__((objc_arc_weak_reference_unavailable)) +#define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER +#define DEPRECATED __attribute__((deprecated)) + +typedef char BOOL; +@class NSString; +@protocol NSCopying @end + +@interface NSObject <NSCopying> +@end + +@interface NSDictionary : NSObject +@end + +@interface I : NSObject { + int ivarVal; +} +@property (weak) NSString *WeakProp; + +@property (retain) NSString *StrongProp; + +@property (retain) NSString *UnavailProp __attribute__((unavailable)); +- (void) setUnavailProp : (NSString *)Val; + +@property (retain) NSString *UnavailProp1 __attribute__((unavailable)); + +@property (retain) NSString *UnavailProp2; +- (void) setUnavailProp2 : (NSString *)Val __attribute__((unavailable)); + +@property (copy) NSDictionary *undoAction; +@end + +@implementation I +@end + +@class NSArray; + +@interface MyClass2 { +@private + NSArray *_names1; + NSArray *_names2; + NSArray *_names3; + NSArray *_names4; +} +@property (retain) NSArray *names2; +@property (retain) NSArray *names3; +@property (retain) NSArray *names4; +@property (retain) NSArray *names1; +@end + +// Properties that contain the name "delegate" or "dataSource", +// or have exact name "target" have unsafe_unretained attribute. +@interface NSInvocation +@property (assign) id target; + +@property (assign) id dataSource; + +@property (assign) id xxxdelegateYYY; + + +@property (retain) id MYtarget; + +@property (retain) id targetX; + +@property int value; + +@property (getter=isContinuous) BOOL continuous; + +- (id) isAnObject; +- (void)setAnObject : (id) object; + +@property (getter=isinValid, readonly) BOOL inValid; +- (void) setInValid : (BOOL) arg; + +- (void) Nothing; +@property (readonly) int Length; +@property (readonly, retain) id object; ++ (double) D; +@property (readonly) void *JSObject WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER); +@property (getter=isIgnoringInteractionEvents, readonly) BOOL ignoringInteractionEvents; + +@property (getter=getStringValue, retain) NSString *stringValue; +@property (getter=getCounterValue, readonly) BOOL counterValue; +@property (getter=getns_dixtionary, readonly, retain) NSDictionary *ns_dixtionary; + +- (BOOL)is3bar; // watch out +- (NSString *)get3foo; // watch out + +@property (getter=getM, readonly) BOOL m; +@property (getter=getMA, readonly) BOOL MA; +@property (getter=getALL, readonly) BOOL ALL; +@property (getter=getMANY, readonly) BOOL MANY; +@property (getter=getSome, readonly) BOOL some; +@end + + +@interface NSInvocation(CAT) +@property (assign) id target; + +@property (assign) id dataSource; + +@property (assign) id xxxdelegateYYY; + + +@property (retain) id MYtarget; + +@property (retain) id targetX; + +@property int value; + +@property (getter=isContinuous) BOOL continuous; + +- (id) isAnObject; +- (void)setAnObject : (id) object; + +@property (getter=isinValid, readonly) BOOL inValid; +- (void) setInValid : (BOOL) arg; + +- (void) Nothing; +@property (readonly) int Length; +@property (readonly, retain) id object; ++ (double) D; + +- (BOOL)is3bar; // watch out +- (NSString *)get3foo; // watch out + +@property (getter=getM, readonly) BOOL m; +@property (getter=getMA, readonly) BOOL MA; +@property (getter=getALL, readonly) BOOL ALL; +@property (getter=getMANY, readonly) BOOL MANY; +@property (getter=getSome, readonly) BOOL some; +@end + +DEPRECATED +@interface I_DEP +- (BOOL) isinValid; +- (void) setInValid : (BOOL) arg; +@end + +@interface AnotherOne +- (BOOL) isinValid DEPRECATED; +- (void) setInValid : (BOOL) arg; +- (id)MYtarget; +- (void)setMYtarget: (id)target DEPRECATED; +- (BOOL) getM DEPRECATED; + +- (id)xxxdelegateYYY DEPRECATED; +- (void)setXxxdelegateYYY:(id)delegate DEPRECATED; +@end + +// rdar://14987909 +#define NS_AVAILABLE __attribute__((availability(macosx,introduced=10.0))) +#define NORETURN __attribute__((noreturn)) +#define ALIGNED __attribute__((aligned(16))) + +@interface NSURL +// Do not infer a property. +@property (retain) NSURL *appStoreReceiptURL NS_AVAILABLE; +- (void) setAppStoreReceiptURL : (NSURL *)object; + +@property (retain) NSURL *appStoreReceiptURLX NS_AVAILABLE; + +// Do not infer a property. +@property (retain) NSURL *appStoreReceiptURLY ; +- (void) setAppStoreReceiptURLY : (NSURL *)object NS_AVAILABLE; + +@property (readonly, retain) id OkToInfer NS_AVAILABLE; + +// Do not infer a property. +@property (retain) NSURL *appStoreReceiptURLZ ; +- (void) setAppStoreReceiptURLZ : (NSURL *)object NS_AVAILABLE; + +// Do not infer a property. +- (id) t1 NORETURN NS_AVAILABLE; +- (void) setT1 : (id) arg NS_AVAILABLE; + +@property (retain) id method1 ALIGNED NS_AVAILABLE; + +- (NSURL *)init; // No Change ++ (id)alloc; // No Change + +- (BOOL)is1stClass; // Not a valid property +@property (getter=isClass, readonly) BOOL class; // This is a valid property 'class' is not a keyword in ObjC +- (BOOL)isDouble; // Not a valid property + +@end + +// rdar://15082818 +@class NSMutableDictionary; + +@interface NSArray +@property (readonly, copy) id (^expressionBlock)(id, NSArray *, NSMutableDictionary *); +@property (copy) id (^MyBlock)(id, NSArray *, NSMutableDictionary *); +@property (readonly) id (*expressionFuncptr)(id, NSArray *, NSMutableDictionary *); +@property id (*MyFuncptr)(id, NSArray *, NSMutableDictionary *); +@end diff --git a/test/ARCMT/objcmt-deprecated-category.m b/test/ARCMT/objcmt-deprecated-category.m new file mode 100644 index 0000000..5939e5a --- /dev/null +++ b/test/ARCMT/objcmt-deprecated-category.m @@ -0,0 +1,48 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -objcmt-migrate-annotation -mt-migrate-directory %t %s -x objective-c -triple x86_64-apple-darwin11 +// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s.result +// rdar://15337661 + +#define DEPRECATED __attribute__((deprecated)) + +@interface NSArray +- (int)one; +@end + +@interface NSArray (NSDraggingSourceDeprecated) + +/* This method is unsafe because it could potentially cause buffer overruns. You should use -getObjects:range: instead. +*/ +- (void)getObjects:(id __unsafe_unretained [])objects; +- (void)dep_getObjects:(id __unsafe_unretained [])dep_objects DEPRECATED; + +@end + +@interface NSArray (NSDeprecated) + +/* This method is unsafe because it could potentially cause buffer overruns. You should use -getObjects:range: instead. +*/ +- (void)dep_getObjects:(id __unsafe_unretained [])dep_objects DEPRECATED; +- (void)getObjects:(id __unsafe_unretained [])objects; +@property int P1; +@property int P2 DEPRECATED; +@end + +@interface NSArray (DraggingSourceDeprecated) + +/* This method is unsafe because it could potentially cause buffer overruns. You should use -getObjects:range: instead. +*/ +- (void)getObjects:(id __unsafe_unretained [])objects; +- (void)dep_getObjects:(id __unsafe_unretained [])dep_objects DEPRECATED; +@property int P1; +@property int P2 DEPRECATED; + +@end + +@interface NSArray (Deprecated) +- (void)getObjects:(id __unsafe_unretained [])objects; +- (void)dep_getObjects:(id __unsafe_unretained [])dep_objects DEPRECATED; +@property int P1; +@property int P2 DEPRECATED; +@end diff --git a/test/ARCMT/objcmt-deprecated-category.m.result b/test/ARCMT/objcmt-deprecated-category.m.result new file mode 100644 index 0000000..3cb1000 --- /dev/null +++ b/test/ARCMT/objcmt-deprecated-category.m.result @@ -0,0 +1,48 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -objcmt-migrate-annotation -mt-migrate-directory %t %s -x objective-c -triple x86_64-apple-darwin11 +// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s.result +// rdar://15337661 + +#define DEPRECATED __attribute__((deprecated)) + +@interface NSArray +- (int)one; +@end + +@interface NSArray (NSDraggingSourceDeprecated) + +/* This method is unsafe because it could potentially cause buffer overruns. You should use -getObjects:range: instead. +*/ +- (void)getObjects:(id __unsafe_unretained [])objects DEPRECATED; +- (void)dep_getObjects:(id __unsafe_unretained [])dep_objects DEPRECATED; + +@end + +@interface NSArray (NSDeprecated) + +/* This method is unsafe because it could potentially cause buffer overruns. You should use -getObjects:range: instead. +*/ +- (void)dep_getObjects:(id __unsafe_unretained [])dep_objects DEPRECATED; +- (void)getObjects:(id __unsafe_unretained [])objects DEPRECATED; +@property int P1 DEPRECATED; +@property int P2 DEPRECATED; +@end + +@interface NSArray (DraggingSourceDeprecated) + +/* This method is unsafe because it could potentially cause buffer overruns. You should use -getObjects:range: instead. +*/ +- (void)getObjects:(id __unsafe_unretained [])objects DEPRECATED; +- (void)dep_getObjects:(id __unsafe_unretained [])dep_objects DEPRECATED; +@property int P1 DEPRECATED; +@property int P2 DEPRECATED; + +@end + +@interface NSArray (Deprecated) +- (void)getObjects:(id __unsafe_unretained [])objects DEPRECATED; +- (void)dep_getObjects:(id __unsafe_unretained [])dep_objects DEPRECATED; +@property int P1 DEPRECATED; +@property int P2 DEPRECATED; +@end diff --git a/test/ARCMT/objcmt-instancetype-2.m b/test/ARCMT/objcmt-instancetype-2.m new file mode 100644 index 0000000..fb59265 --- /dev/null +++ b/test/ARCMT/objcmt-instancetype-2.m @@ -0,0 +1,103 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -objcmt-migrate-instancetype -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 +// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result + +typedef unsigned int NSUInteger; +typedef int NSInteger; +typedef char BOOL; +@class NSData, NSError, NSProtocolChecker, NSObject; +@class NSPortNameServer, NSTimeZone; + +@interface NSMutableString +@end + +@interface NSString @end + +@class NSString, NSURL; +@interface NSString (NSStringDeprecated) ++ (id)stringWithContentsOfFile:(NSString *)path __attribute__((availability(macosx,introduced=10.0 ,message="" ))); ++ (id)stringWithContentsOfURL:(NSURL *)url __attribute__((availability(macosx,introduced=10.0 ,message="" ))); ++ (id)stringWithCString:(const char *)bytes length:(NSUInteger)length __attribute__((availability(macosx,introduced=10.0 ,message="" ))); ++ (id)stringWithCString:(const char *)bytes __attribute__((availability(macosx,introduced=10.0 ,message="" ))); +@end + + +typedef enum NSURLBookmarkResolutionOptions { + Bookmark +} NSURLBookmarkResolutionOptions; + +@interface NSURL ++ (id)URLWithString:(NSString *)URLString; ++ (id)URLWithString:(NSString *)URLString relativeToURL:(NSURL *)baseURL; ++ (id)URLByResolvingBookmarkData:(NSData *)bookmarkData options:(NSURLBookmarkResolutionOptions)options relativeToURL:(NSURL *)relativeURL bookmarkDataIsStale:(BOOL *)isStale error:(NSError **)error __attribute__((availability(macosx,introduced=10.6))); +@end + +@class NSDictionary; +@interface NSError ++ (id)errorWithDomain:(NSString *)domain code:(NSInteger)code userInfo:(NSDictionary *)dict; +@end + + +@interface NSMutableString (NSMutableStringExtensionMethods) ++ (id)stringWithCapacity:(NSUInteger)capacity; +@end + +@interface NSMutableData ++ (id)dataWithCapacity:(NSUInteger)aNumItems; ++ (id)dataWithLength:(NSUInteger)length; +@end + +@interface NSMutableDictionary @end + +@interface NSMutableDictionary (NSSharedKeySetDictionary) ++ (id )dictionaryWithSharedKeySet:(id)keyset __attribute__((availability(macosx,introduced=10.8))); +@end + +@interface NSProtocolChecker ++ (id)protocolCheckerWithTarget:(NSObject *)anObject protocol:(Protocol *)aProtocol; +@end + +@interface NSConnection ++ (id)connectionWithRegisteredName:(NSString *)name host:(NSString *)hostName; ++ (id)connectionWithRegisteredName:(NSString *)name host:(NSString *)hostName usingNameServer:(NSPortNameServer *)server; +@end + +@interface NSDate ++ (id)dateWithString:(NSString *)aString __attribute__((availability(macosx,introduced=10.4))); +@end + +@interface NSCalendarDate : NSDate ++ (id)calendarDate __attribute__((availability(macosx,introduced=10.4))); ++ (id)dateWithString:(NSString *)description calendarFormat:(NSString *)format locale:(id)locale __attribute__((availability(macosx,introduced=10.4))); ++ (id)dateWithString:(NSString *)description calendarFormat:(NSString *)format __attribute__((availability(macosx,introduced=10.4))); ++ (id)dateWithYear:(NSInteger)year month:(NSUInteger)month day:(NSUInteger)day hour:(NSUInteger)hour minute:(NSUInteger)minute second:(NSUInteger)second timeZone:(NSTimeZone *)aTimeZone __attribute__((availability(macosx,introduced=10.4))); +@end + +@interface NSUserDefaults ++ (id) standardUserDefaults; +@end + +@interface NSNotificationCenter ++ (id) defaultCenter; ++ sharedCenter; +@end + +@interface UIApplication ++ (id)sharedApplication; ++ defaultApplication; +@end + +//===----------------------------------------------------------------------===// +// Method name that has a null IdentifierInfo* for its first selector slot. +// This test just makes sure that we handle it. +//===----------------------------------------------------------------------===// +@interface TestNullIdentifier +@end + +@implementation TestNullIdentifier ++ (id):(int)x, ... { + return 0; +} +@end + diff --git a/test/ARCMT/objcmt-instancetype-2.m.result b/test/ARCMT/objcmt-instancetype-2.m.result new file mode 100644 index 0000000..8837e97 --- /dev/null +++ b/test/ARCMT/objcmt-instancetype-2.m.result @@ -0,0 +1,103 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -objcmt-migrate-instancetype -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 +// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result + +typedef unsigned int NSUInteger; +typedef int NSInteger; +typedef char BOOL; +@class NSData, NSError, NSProtocolChecker, NSObject; +@class NSPortNameServer, NSTimeZone; + +@interface NSMutableString +@end + +@interface NSString @end + +@class NSString, NSURL; +@interface NSString (NSStringDeprecated) ++ (instancetype)stringWithContentsOfFile:(NSString *)path __attribute__((availability(macosx,introduced=10.0 ,message="" ))); ++ (instancetype)stringWithContentsOfURL:(NSURL *)url __attribute__((availability(macosx,introduced=10.0 ,message="" ))); ++ (instancetype)stringWithCString:(const char *)bytes length:(NSUInteger)length __attribute__((availability(macosx,introduced=10.0 ,message="" ))); ++ (instancetype)stringWithCString:(const char *)bytes __attribute__((availability(macosx,introduced=10.0 ,message="" ))); +@end + + +typedef enum NSURLBookmarkResolutionOptions { + Bookmark +} NSURLBookmarkResolutionOptions; + +@interface NSURL ++ (instancetype)URLWithString:(NSString *)URLString; ++ (instancetype)URLWithString:(NSString *)URLString relativeToURL:(NSURL *)baseURL; ++ (instancetype)URLByResolvingBookmarkData:(NSData *)bookmarkData options:(NSURLBookmarkResolutionOptions)options relativeToURL:(NSURL *)relativeURL bookmarkDataIsStale:(BOOL *)isStale error:(NSError **)error __attribute__((availability(macosx,introduced=10.6))); +@end + +@class NSDictionary; +@interface NSError ++ (instancetype)errorWithDomain:(NSString *)domain code:(NSInteger)code userInfo:(NSDictionary *)dict; +@end + + +@interface NSMutableString (NSMutableStringExtensionMethods) ++ (instancetype)stringWithCapacity:(NSUInteger)capacity; +@end + +@interface NSMutableData ++ (instancetype)dataWithCapacity:(NSUInteger)aNumItems; ++ (instancetype)dataWithLength:(NSUInteger)length; +@end + +@interface NSMutableDictionary @end + +@interface NSMutableDictionary (NSSharedKeySetDictionary) ++ (instancetype )dictionaryWithSharedKeySet:(id)keyset __attribute__((availability(macosx,introduced=10.8))); +@end + +@interface NSProtocolChecker ++ (instancetype)protocolCheckerWithTarget:(NSObject *)anObject protocol:(Protocol *)aProtocol; +@end + +@interface NSConnection ++ (instancetype)connectionWithRegisteredName:(NSString *)name host:(NSString *)hostName; ++ (instancetype)connectionWithRegisteredName:(NSString *)name host:(NSString *)hostName usingNameServer:(NSPortNameServer *)server; +@end + +@interface NSDate ++ (instancetype)dateWithString:(NSString *)aString __attribute__((availability(macosx,introduced=10.4))); +@end + +@interface NSCalendarDate : NSDate ++ (instancetype)calendarDate __attribute__((availability(macosx,introduced=10.4))); ++ (instancetype)dateWithString:(NSString *)description calendarFormat:(NSString *)format locale:(id)locale __attribute__((availability(macosx,introduced=10.4))); ++ (instancetype)dateWithString:(NSString *)description calendarFormat:(NSString *)format __attribute__((availability(macosx,introduced=10.4))); ++ (instancetype)dateWithYear:(NSInteger)year month:(NSUInteger)month day:(NSUInteger)day hour:(NSUInteger)hour minute:(NSUInteger)minute second:(NSUInteger)second timeZone:(NSTimeZone *)aTimeZone __attribute__((availability(macosx,introduced=10.4))); +@end + +@interface NSUserDefaults ++ (instancetype) standardUserDefaults; +@end + +@interface NSNotificationCenter ++ (NSNotificationCenter*) defaultCenter; ++ (NSNotificationCenter*) sharedCenter; +@end + +@interface UIApplication ++ (UIApplication*)sharedApplication; ++ (UIApplication*) defaultApplication; +@end + +//===----------------------------------------------------------------------===// +// Method name that has a null IdentifierInfo* for its first selector slot. +// This test just makes sure that we handle it. +//===----------------------------------------------------------------------===// +@interface TestNullIdentifier +@end + +@implementation TestNullIdentifier ++ (id):(int)x, ... { + return 0; +} +@end + diff --git a/test/ARCMT/objcmt-instancetype.m b/test/ARCMT/objcmt-instancetype.m new file mode 100644 index 0000000..47dbd7a --- /dev/null +++ b/test/ARCMT/objcmt-instancetype.m @@ -0,0 +1,111 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -objcmt-migrate-instancetype -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 +// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result + +typedef signed char BOOL; +#define nil ((void*) 0) + +@interface NSObject ++ (id)alloc; +@end + +@interface NSString : NSObject ++ (id)stringWithString:(NSString *)string; +- (id)initWithString:(NSString *)aString; +@end + +@implementation NSString : NSObject ++ (id)stringWithString:(NSString *)string { return 0; }; +- (instancetype)initWithString:(NSString *)aString { return 0; }; +@end + +@interface NSArray : NSObject +- (id)objectAtIndex:(unsigned long)index; +- (id)objectAtIndexedSubscript:(int)index; +@end + +@interface NSArray (NSArrayCreation) ++ (id)array; ++ (id)arrayWithObject:(id)anObject; ++ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt; ++ (id)arrayWithObjects:(id)firstObj, ...; ++ arrayWithArray:(NSArray *)array; + +- (id)initWithObjects:(const id [])objects count:(unsigned long)cnt; +- (id)initWithObjects:(id)firstObj, ...; +- (id)initWithArray:(NSArray *)array; + +- (id)objectAtIndex:(unsigned long)index; +@end + +@implementation NSArray (NSArrayCreation) ++ (id)array { return 0; } ++ (id)arrayWithObject:(id)anObject { + return anObject; +} ++ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt { return 0; } ++ (id)arrayWithObjects:(id)firstObj, ... { + return 0; } ++ arrayWithArray:(NSArray *)array { + return 0; +} + +- (id)initWithObjects:(const id [])objects count:(unsigned long)cnt { return 0; } +- (id)initWithObjects:(id)firstObj, ... { return 0; } +- (id)initWithArray:(NSArray *)array { return 0; } + +- (id)objectAtIndex:(unsigned long)index { return 0; } +@end + +@interface NSMutableArray : NSArray +- (void)replaceObjectAtIndex:(unsigned long)index withObject:(id)anObject; +- (void)setObject:(id)object atIndexedSubscript:(int)index; +@end + +@interface NSDictionary : NSObject +- (id)objectForKeyedSubscript:(id)key; +@end + +@interface NSDictionary (NSDictionaryCreation) ++ (id)dictionary; ++ (id)dictionaryWithObject:(id)object forKey:(id)key; ++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; ++ dictionaryWithObjectsAndKeys:(id)firstObject, ...; ++ (id)dictionaryWithDictionary:(NSDictionary *)dict; ++ (id)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; + +- (id)initWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; +- (id)initWithObjectsAndKeys:(id)firstObject, ...; +- (id)initWithDictionary:(NSDictionary *)otherDictionary; +- (id)initWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; + +- (id)objectForKey:(id)aKey; +@end + +@interface NSMutableDictionary : NSDictionary +- (void)setObject:(id)anObject forKey:(id)aKey; +- (void)setObject:(id)object forKeyedSubscript:(id)key; +@end + +@interface NSNumber : NSObject +@end + +@interface NSNumber (NSNumberCreation) ++ (NSNumber *)numberWithInt:(int)value; +@end + +@implementation NSNumber (NSNumberCreation) ++ (NSNumber *)numberWithInt:(int)value { return 0; } +@end + +#define M(x) (x) +#define PAIR(x) @#x, [NSNumber numberWithInt:(x)] +#define TWO(x) ((x), (x)) + +void foo() { + NSString *str = M([NSString stringWithString:@"foo"]); // expected-warning {{redundant}} + str = [[NSString alloc] initWithString:@"foo"]; // expected-warning {{redundant}} + NSArray *arr = [NSArray arrayWithArray:@[str]]; // expected-warning {{redundant}} + NSDictionary *dict = [NSDictionary dictionaryWithDictionary:@{str: arr}]; // expected-warning {{redundant}} +} diff --git a/test/ARCMT/objcmt-instancetype.m.result b/test/ARCMT/objcmt-instancetype.m.result new file mode 100644 index 0000000..ce51678 --- /dev/null +++ b/test/ARCMT/objcmt-instancetype.m.result @@ -0,0 +1,111 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -objcmt-migrate-instancetype -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 +// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result + +typedef signed char BOOL; +#define nil ((void*) 0) + +@interface NSObject ++ (id)alloc; +@end + +@interface NSString : NSObject ++ (instancetype)stringWithString:(NSString *)string; +- (instancetype)initWithString:(NSString *)aString; +@end + +@implementation NSString : NSObject ++ (instancetype)stringWithString:(NSString *)string { return 0; }; +- (instancetype)initWithString:(NSString *)aString { return 0; }; +@end + +@interface NSArray : NSObject +- (id)objectAtIndex:(unsigned long)index; +- (id)objectAtIndexedSubscript:(int)index; +@end + +@interface NSArray (NSArrayCreation) ++ (instancetype)array; ++ (instancetype)arrayWithObject:(id)anObject; ++ (instancetype)arrayWithObjects:(const id [])objects count:(unsigned long)cnt; ++ (instancetype)arrayWithObjects:(id)firstObj, ...; ++ (instancetype) arrayWithArray:(NSArray *)array; + +- (instancetype)initWithObjects:(const id [])objects count:(unsigned long)cnt; +- (instancetype)initWithObjects:(id)firstObj, ...; +- (instancetype)initWithArray:(NSArray *)array; + +- (id)objectAtIndex:(unsigned long)index; +@end + +@implementation NSArray (NSArrayCreation) ++ (instancetype)array { return 0; } ++ (instancetype)arrayWithObject:(id)anObject { + return anObject; +} ++ (instancetype)arrayWithObjects:(const id [])objects count:(unsigned long)cnt { return 0; } ++ (instancetype)arrayWithObjects:(id)firstObj, ... { + return 0; } ++ (instancetype) arrayWithArray:(NSArray *)array { + return 0; +} + +- (instancetype)initWithObjects:(const id [])objects count:(unsigned long)cnt { return 0; } +- (instancetype)initWithObjects:(id)firstObj, ... { return 0; } +- (instancetype)initWithArray:(NSArray *)array { return 0; } + +- (id)objectAtIndex:(unsigned long)index { return 0; } +@end + +@interface NSMutableArray : NSArray +- (void)replaceObjectAtIndex:(unsigned long)index withObject:(id)anObject; +- (void)setObject:(id)object atIndexedSubscript:(int)index; +@end + +@interface NSDictionary : NSObject +- (id)objectForKeyedSubscript:(id)key; +@end + +@interface NSDictionary (NSDictionaryCreation) ++ (instancetype)dictionary; ++ (instancetype)dictionaryWithObject:(id)object forKey:(id)key; ++ (instancetype)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; ++ (instancetype) dictionaryWithObjectsAndKeys:(id)firstObject, ...; ++ (instancetype)dictionaryWithDictionary:(NSDictionary *)dict; ++ (instancetype)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; + +- (instancetype)initWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; +- (instancetype)initWithObjectsAndKeys:(id)firstObject, ...; +- (instancetype)initWithDictionary:(NSDictionary *)otherDictionary; +- (instancetype)initWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; + +- (id)objectForKey:(id)aKey; +@end + +@interface NSMutableDictionary : NSDictionary +- (void)setObject:(id)anObject forKey:(id)aKey; +- (void)setObject:(id)object forKeyedSubscript:(id)key; +@end + +@interface NSNumber : NSObject +@end + +@interface NSNumber (NSNumberCreation) ++ (NSNumber *)numberWithInt:(int)value; +@end + +@implementation NSNumber (NSNumberCreation) ++ (NSNumber *)numberWithInt:(int)value { return 0; } +@end + +#define M(x) (x) +#define PAIR(x) @#x, [NSNumber numberWithInt:(x)] +#define TWO(x) ((x), (x)) + +void foo() { + NSString *str = M([NSString stringWithString:@"foo"]); // expected-warning {{redundant}} + str = [[NSString alloc] initWithString:@"foo"]; // expected-warning {{redundant}} + NSArray *arr = [NSArray arrayWithArray:@[str]]; // expected-warning {{redundant}} + NSDictionary *dict = [NSDictionary dictionaryWithDictionary:@{str: arr}]; // expected-warning {{redundant}} +} diff --git a/test/ARCMT/objcmt-migrate-all.m b/test/ARCMT/objcmt-migrate-all.m new file mode 100644 index 0000000..7ae898c --- /dev/null +++ b/test/ARCMT/objcmt-migrate-all.m @@ -0,0 +1,135 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -objcmt-migrate-all -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 +// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result +// rdar://15396636 + +#ifndef NS_RETURNS_INNER_POINTER // defined in iOS 6 for sure +#define NS_RETURNS_INNER_POINTER __attribute__((objc_returns_inner_pointer)) +#endif + +#define CF_IMPLICIT_BRIDGING_ENABLED _Pragma("clang arc_cf_code_audited begin") + +#define CF_IMPLICIT_BRIDGING_DISABLED _Pragma("clang arc_cf_code_audited end") + +#if __has_feature(attribute_ns_returns_retained) +#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained)) +#endif +#if __has_feature(attribute_cf_returns_retained) +#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained)) +#endif +#if __has_feature(attribute_ns_returns_not_retained) +#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained)) +#endif +#if __has_feature(attribute_cf_returns_not_retained) +#define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained)) +#endif +#if __has_feature(attribute_ns_consumes_self) +#define NS_CONSUMES_SELF __attribute__((ns_consumes_self)) +#endif +#if __has_feature(attribute_ns_consumed) +#define NS_CONSUMED __attribute__((ns_consumed)) +#endif +#if __has_feature(attribute_cf_consumed) +#define CF_CONSUMED __attribute__((cf_consumed)) +#endif +#if __has_attribute(ns_returns_autoreleased) +#define NS_RETURNS_AUTORELEASED __attribute__((ns_returns_autoreleased)) +#endif + +#define NS_AVAILABLE __attribute__((availability(macosx,introduced=10.0))) + +CF_IMPLICIT_BRIDGING_ENABLED + +typedef unsigned long CFTypeID; +typedef unsigned long CFOptionFlags; +typedef unsigned long CFHashCode; + +typedef signed long CFIndex; /*AnyObj*/ +typedef const struct __CFArray * CFArrayRef; +typedef struct { + CFIndex location; + CFIndex length; +} CFRange; + +typedef void (*CFArrayApplierFunction)(const void *value, void *context); + +typedef enum CFComparisonResult : CFIndex CFComparisonResult; enum CFComparisonResult : CFIndex { + kCFCompareLessThan = -1L, + kCFCompareEqualTo = 0, + kCFCompareGreaterThan = 1 +}; + + +typedef CFComparisonResult (*CFComparatorFunction)(const void *val1, const void *val2, void *context); + +typedef struct __CFArray * CFMutableArrayRef; + +typedef const struct __CFAttributedString *CFAttributedStringRef; +typedef struct __CFAttributedString *CFMutableAttributedStringRef; + +typedef const struct __CFAllocator * CFAllocatorRef; + +typedef const struct __CFString * CFStringRef; +typedef struct __CFString * CFMutableStringRef; + +typedef const struct __CFDictionary * CFDictionaryRef; +typedef struct __CFDictionary * CFMutableDictionaryRef; + +typedef struct CGImage *CGImageRef; + +typedef struct OpaqueJSValue* JSObjectRef; + +typedef JSObjectRef TTJSObjectRef; +typedef unsigned int NSUInteger; + +CF_IMPLICIT_BRIDGING_DISABLED + +@interface I +- (void*) ReturnsInnerPointer; +- (int*) AlreadyReturnsInnerPointer NS_RETURNS_INNER_POINTER; +@end + +@interface UIImage +- (CGImageRef)CGImage; +@end + +@interface NSData +- (void *)bytes; +- (void **) ptr_bytes __attribute__((availability(macosx,unavailable))); +@end + +@interface NSMutableData +- (void *)mutableBytes __attribute__((deprecated)) __attribute__((unavailable)); +@end + +@interface JS +- (JSObjectRef)JSObject; +- (TTJSObjectRef)JSObject1; +- (JSObjectRef*)JSObject2; +@end + +// rdar://15044991 +typedef void *SecTrustRef; + +@interface NSURLProtectionSpace +@property (readonly) SecTrustRef serverTrust NS_AVAILABLE; +- (void *) FOO NS_AVAILABLE; +@property (readonly) void * mitTrust NS_AVAILABLE; + +@property (readonly) void * mittiTrust; + +@property (readonly) SecTrustRef XserverTrust; + +- (SecTrustRef) FOO1 NS_AVAILABLE; + ++ (const NSURLProtectionSpace *)ProtectionSpace; + +// pointer personality functions +@property NSUInteger (*hashFunction)(const void *item, NSUInteger (*size)(const void *item)); +@end + +@interface MustNotMigrateToInnerPointer +- (void*) nono; +- (void) setNono : (void*) val; +@end diff --git a/test/ARCMT/objcmt-migrate-all.m.result b/test/ARCMT/objcmt-migrate-all.m.result new file mode 100644 index 0000000..d2ee409 --- /dev/null +++ b/test/ARCMT/objcmt-migrate-all.m.result @@ -0,0 +1,134 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -objcmt-migrate-all -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 +// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result +// rdar://15396636 + +#ifndef NS_RETURNS_INNER_POINTER // defined in iOS 6 for sure +#define NS_RETURNS_INNER_POINTER __attribute__((objc_returns_inner_pointer)) +#endif + +#define CF_IMPLICIT_BRIDGING_ENABLED _Pragma("clang arc_cf_code_audited begin") + +#define CF_IMPLICIT_BRIDGING_DISABLED _Pragma("clang arc_cf_code_audited end") + +#if __has_feature(attribute_ns_returns_retained) +#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained)) +#endif +#if __has_feature(attribute_cf_returns_retained) +#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained)) +#endif +#if __has_feature(attribute_ns_returns_not_retained) +#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained)) +#endif +#if __has_feature(attribute_cf_returns_not_retained) +#define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained)) +#endif +#if __has_feature(attribute_ns_consumes_self) +#define NS_CONSUMES_SELF __attribute__((ns_consumes_self)) +#endif +#if __has_feature(attribute_ns_consumed) +#define NS_CONSUMED __attribute__((ns_consumed)) +#endif +#if __has_feature(attribute_cf_consumed) +#define CF_CONSUMED __attribute__((cf_consumed)) +#endif +#if __has_attribute(ns_returns_autoreleased) +#define NS_RETURNS_AUTORELEASED __attribute__((ns_returns_autoreleased)) +#endif + +#define NS_AVAILABLE __attribute__((availability(macosx,introduced=10.0))) + +CF_IMPLICIT_BRIDGING_ENABLED + +typedef unsigned long CFTypeID; +typedef unsigned long CFOptionFlags; +typedef unsigned long CFHashCode; + +typedef signed long CFIndex; /*AnyObj*/ +typedef const struct __CFArray * CFArrayRef; +typedef struct { + CFIndex location; + CFIndex length; +} CFRange; + +typedef void (*CFArrayApplierFunction)(const void *value, void *context); + +typedef enum CFComparisonResult : CFIndex CFComparisonResult; enum CFComparisonResult : CFIndex { + kCFCompareLessThan = -1L, + kCFCompareEqualTo = 0, + kCFCompareGreaterThan = 1 +}; + + +typedef CFComparisonResult (*CFComparatorFunction)(const void *val1, const void *val2, void *context); + +typedef struct __CFArray * CFMutableArrayRef; + +typedef const struct __CFAttributedString *CFAttributedStringRef; +typedef struct __CFAttributedString *CFMutableAttributedStringRef; + +typedef const struct __CFAllocator * CFAllocatorRef; + +typedef const struct __CFString * CFStringRef; +typedef struct __CFString * CFMutableStringRef; + +typedef const struct __CFDictionary * CFDictionaryRef; +typedef struct __CFDictionary * CFMutableDictionaryRef; + +typedef struct CGImage *CGImageRef; + +typedef struct OpaqueJSValue* JSObjectRef; + +typedef JSObjectRef TTJSObjectRef; +typedef unsigned int NSUInteger; + +CF_IMPLICIT_BRIDGING_DISABLED + +@interface I +@property (nonatomic, readonly) void *ReturnsInnerPointer; +@property (nonatomic, readonly) int *AlreadyReturnsInnerPointer NS_RETURNS_INNER_POINTER; +@end + +@interface UIImage +@property (nonatomic, readonly) CGImageRef CGImage CF_RETURNS_NOT_RETAINED; +@end + +@interface NSData +@property (nonatomic, readonly) void *bytes; +@property (nonatomic, readonly) void **ptr_bytes __attribute__((availability(macosx,unavailable))); +@end + +@interface NSMutableData +@property (nonatomic, readonly) void *mutableBytes __attribute__((deprecated)) __attribute__((unavailable)); +@end + +@interface JS +@property (nonatomic, readonly) JSObjectRef JSObject; +@property (nonatomic, readonly) TTJSObjectRef JSObject1; +@property (nonatomic, readonly) JSObjectRef *JSObject2; +@end + +// rdar://15044991 +typedef void *SecTrustRef; + +@interface NSURLProtectionSpace +@property (readonly) SecTrustRef serverTrust NS_AVAILABLE; +@property (nonatomic, readonly) void *FOO NS_AVAILABLE; +@property (readonly) void * mitTrust NS_AVAILABLE; + +@property (readonly) void * mittiTrust; + +@property (readonly) SecTrustRef XserverTrust; + +@property (nonatomic, readonly) SecTrustRef FOO1 NS_AVAILABLE; + ++ (const NSURLProtectionSpace *)ProtectionSpace; + +// pointer personality functions +@property NSUInteger (*hashFunction)(const void *item, NSUInteger (*size)(const void *item)); +@end + +@interface MustNotMigrateToInnerPointer +@property (nonatomic) void *nono; +@end diff --git a/test/ARCMT/objcmt-ns-macros.m b/test/ARCMT/objcmt-ns-macros.m new file mode 100644 index 0000000..1bf55d8 --- /dev/null +++ b/test/ARCMT/objcmt-ns-macros.m @@ -0,0 +1,296 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -objcmt-migrate-ns-macros -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 +// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result + +typedef long NSInteger; +typedef unsigned long NSUInteger; + +#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type +#define NS_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type +#define DEPRECATED __attribute__((deprecated)) + +enum { + blah, + blarg +}; +typedef NSInteger wibble; + +enum { + UIViewAutoresizingNone = 0, + UIViewAutoresizingFlexibleLeftMargin, + UIViewAutoresizingFlexibleWidth, + UIViewAutoresizingFlexibleRightMargin, + UIViewAutoresizingFlexibleTopMargin, + UIViewAutoresizingFlexibleHeight, + UIViewAutoresizingFlexibleBottomMargin +}; +typedef NSUInteger UITableViewCellStyle; + +typedef enum { + UIViewAnimationTransitionNone, + UIViewAnimationTransitionFlipFromLeft, + UIViewAnimationTransitionFlipFromRight, + UIViewAnimationTransitionCurlUp, + UIViewAnimationTransitionCurlDown, +} UIViewAnimationTransition; + +typedef enum { + UIViewOne = 0, + UIViewTwo = 1 << 0, + UIViewThree = 1 << 1, + UIViewFour = 1 << 2, + UIViewFive = 1 << 3, + UIViewSix = 1 << 4, + UIViewSeven = 1 << 5 +} UITableView; + +enum { + UIOne = 0, + UITwo = 0x1, + UIthree = 0x8, + UIFour = 0x100 +}; +typedef NSInteger UI; + +typedef enum { + UIP2One = 0, + UIP2Two = 0x1, + UIP2three = 0x8, + UIP2Four = 0x100 +} UIPOWER2; + +enum { + UNOne, + UNTwo +}; + +// Should use NS_ENUM even though it is all power of 2. +enum { + UIKOne = 1, + UIKTwo = 2, +}; +typedef NSInteger UIK; + +typedef enum { + NSTickMarkBelow = 0, + NSTickMarkAbove = 1, + NSTickMarkLeft = NSTickMarkAbove, + NSTickMarkRight = NSTickMarkBelow +} NSTickMarkPosition; + +enum { + UIViewNone = 0x0, + UIViewMargin = 0x1, + UIViewWidth = 0x2, + UIViewRightMargin = 0x3, + UIViewBottomMargin = 0xbadbeef +}; +typedef NSInteger UITableStyle; + +enum { + UIView0 = 0, + UIView1 = 0XBADBEEF +}; +typedef NSInteger UIStyle; + +enum { + NSTIFFFileType, + NSBMPFileType, + NSGIFFileType, + NSJPEGFileType, + NSPNGFileType, + NSJPEG2000FileType +}; +typedef NSUInteger NSBitmapImageFileType; + +enum { + NSWarningAlertStyle = 0, + NSInformationalAlertStyle = 1, + NSCriticalAlertStyle = 2 +}; +typedef NSUInteger NSAlertStyle; + +enum { + D_NSTIFFFileType, + D_NSBMPFileType, + D_NSGIFFileType, + D_NSJPEGFileType, + D_NSPNGFileType, + D_NSJPEG2000FileType +}; +typedef NSUInteger D_NSBitmapImageFileType DEPRECATED; + +typedef enum { + D_NSTickMarkBelow = 0, + D_NSTickMarkAbove = 1 +} D_NSTickMarkPosition DEPRECATED; + + +#define NS_ENUM_AVAILABLE(X,Y) + +enum { + NSFStrongMemory NS_ENUM_AVAILABLE(10_5, 6_0) = (0UL << 0), + NSFOpaqueMemory NS_ENUM_AVAILABLE(10_5, 6_0) = (2UL << 0), + NSFMallocMemory NS_ENUM_AVAILABLE(10_5, 6_0) = (3UL << 0), + NSFMachVirtualMemory NS_ENUM_AVAILABLE(10_5, 6_0) = (4UL << 0), + NSFWeakMemory NS_ENUM_AVAILABLE(10_8, 6_0) = (5UL << 0), + + NSFObjectPersonality NS_ENUM_AVAILABLE(10_5, 6_0) = (0UL << 8), + NSFOpaquePersonality NS_ENUM_AVAILABLE(10_5, 6_0) = (1UL << 8), + NSFObjectPointerPersonality NS_ENUM_AVAILABLE(10_5, 6_0) = (2UL << 8), + NSFCStringPersonality NS_ENUM_AVAILABLE(10_5, 6_0) = (3UL << 8), + NSFStructPersonality NS_ENUM_AVAILABLE(10_5, 6_0) = (4UL << 8), + NSFIntegerPersonality NS_ENUM_AVAILABLE(10_5, 6_0) = (5UL << 8), + NSFCopyIn NS_ENUM_AVAILABLE(10_5, 6_0) = (1UL << 16), +}; + +typedef NSUInteger NSFOptions; + +typedef enum { + UIP0One = 0, + UIP0Two = 1, + UIP0Three = 2, + UIP0Four = 10, + UIP0Last = 0x100 +} UIP; + +typedef enum { + UIPZero = 0x0, + UIPOne = 0x1, + UIPTwo = 0x2, + UIP10 = 0x10, + UIPHundred = 0x100 +} UIP_3; + +typedef enum { + UIP4Zero = 0x0, + UIP4One = 0x1, + UIP4Two = 0x2, + UIP410 = 0x10, + UIP4Hundred = 100 +} UIP4_3; + +typedef enum { + UIP5Zero = 0x0, + UIP5Two = 0x2, + UIP510 = 0x3, + UIP5Hundred = 0x4 +} UIP5_3; + +typedef enum { + UIP6Zero = 0x0, + UIP6One = 0x1, + UIP6Two = 0x2, + UIP610 = 10, + UIP6Hundred = 0x100 +} UIP6_3; + +typedef enum { + UIP7Zero = 0x0, + UIP7One = 1, + UIP7Two = 0x2, + UIP710 = 10, + UIP7Hundred = 100 +} UIP7_3; + + +typedef enum { + Random = 0, + Random1 = 2, + Random2 = 4, + Random3 = 0x12345, + Random4 = 0x3444444, + Random5 = 0xbadbeef, + Random6 +} UIP8_3; + +// rdar://15200602 +#define NS_AVAILABLE_MAC(X) __attribute__((availability(macosx,introduced=X))) +#define NS_ENUM_AVAILABLE_MAC(X) __attribute__((availability(macosx,introduced=X))) + +enum { + NSModalResponseStop = (-1000), // Also used as the default response for sheets + NSModalResponseAbort = (-1001), + NSModalResponseContinue = (-1002), +} NS_ENUM_AVAILABLE_MAC(10.9); +typedef NSInteger NSModalResponse NS_AVAILABLE_MAC(10.9); + +// rdar://15201056 +typedef NSUInteger FarFarAwayOptions; + +// rdar://15200915 +typedef NSUInteger FarAwayOptions; +enum { + NSWorkspaceLaunchAndPrint = 0x00000002, + NSWorkspaceLaunchWithErrorPresentation = 0x00000040, + NSWorkspaceLaunchInhibitingBackgroundOnly = 0x00000080, + NSWorkspaceLaunchWithoutAddingToRecents = 0x00000100, + NSWorkspaceLaunchWithoutActivation = 0x00000200, + NSWorkspaceLaunchAsync = 0x00010000, + NSWorkspaceLaunchAllowingClassicStartup = 0x00020000, + NSWorkspaceLaunchPreferringClassic = 0x00040000, + NSWorkspaceLaunchNewInstance = 0x00080000, + NSWorkspaceLaunchAndHide = 0x00100000, + NSWorkspaceLaunchAndHideOthers = 0x00200000, + NSWorkspaceLaunchDefault = NSWorkspaceLaunchAsync | + NSWorkspaceLaunchAllowingClassicStartup +}; +typedef NSUInteger NSWorkspaceLaunchOptions; + +enum { + NSExcludeQuickDrawElementsIconCreationOption = 1 << 1, + NSExclude10_4ElementsIconCreationOption = 1 << 2 +}; +typedef NSUInteger NSExcludeOptions; + +enum { + NSExcludeQuickDrawElementsCreationOption = 1 << 1, + NSExclude10_4ElementsCreationOption = 1 << 2 +}; +typedef NSUInteger NSExcludeCreationOption; + +enum { + FarAway1 = 1 << 1, + FarAway2 = 1 << 2 +}; + +enum { + NSExcludeQuickDrawElementsIconOption = 1 << 1, + NSExclude10_4ElementsIconOption = 1 << 2 +}; +typedef NSUInteger NSExcludeIconOptions; + +@interface INTF { + NSExcludeIconOptions I1; + NSExcludeIconOptions I2; +} +@end + +enum { + FarFarAway1 = 1 << 1, + FarFarAway2 = 1 << 2 +}; + +// rdar://15200915 +typedef NS_OPTIONS(NSUInteger, NSWindowOcclusionState) { + NSWindowOcclusionStateVisible = 1UL << 1, +}; + +typedef NSUInteger NSWindowNumberListOptions; + +enum { + NSDirectSelection = 0, + NSSelectingNext, + NSSelectingPrevious +}; +typedef NSUInteger NSSelectionDirection; + +// standard window buttons +enum { + NSWindowCloseButton, + NSWindowMiniaturizeButton, + NSWindowZoomButton, + NSWindowToolbarButton, + NSWindowDocumentIconButton +}; diff --git a/test/ARCMT/objcmt-ns-macros.m.result b/test/ARCMT/objcmt-ns-macros.m.result new file mode 100644 index 0000000..0b640ac --- /dev/null +++ b/test/ARCMT/objcmt-ns-macros.m.result @@ -0,0 +1,279 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -objcmt-migrate-ns-macros -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 +// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result + +typedef long NSInteger; +typedef unsigned long NSUInteger; + +#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type +#define NS_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type +#define DEPRECATED __attribute__((deprecated)) + +typedef NS_ENUM(NSInteger, wibble) { + blah, + blarg +}; + +typedef NS_ENUM(NSUInteger, UITableViewCellStyle) { + UIViewAutoresizingNone = 0, + UIViewAutoresizingFlexibleLeftMargin, + UIViewAutoresizingFlexibleWidth, + UIViewAutoresizingFlexibleRightMargin, + UIViewAutoresizingFlexibleTopMargin, + UIViewAutoresizingFlexibleHeight, + UIViewAutoresizingFlexibleBottomMargin +}; + +typedef NS_ENUM(NSInteger, UIViewAnimationTransition) { + UIViewAnimationTransitionNone, + UIViewAnimationTransitionFlipFromLeft, + UIViewAnimationTransitionFlipFromRight, + UIViewAnimationTransitionCurlUp, + UIViewAnimationTransitionCurlDown, +} ; + +typedef NS_OPTIONS(NSUInteger, UITableView) { + UIViewOne = 0, + UIViewTwo = 1 << 0, + UIViewThree = 1 << 1, + UIViewFour = 1 << 2, + UIViewFive = 1 << 3, + UIViewSix = 1 << 4, + UIViewSeven = 1 << 5 +} ; + +typedef NS_OPTIONS(NSUInteger, UI) { + UIOne = 0, + UITwo = 0x1, + UIthree = 0x8, + UIFour = 0x100 +}; + +typedef NS_OPTIONS(NSUInteger, UIPOWER2) { + UIP2One = 0, + UIP2Two = 0x1, + UIP2three = 0x8, + UIP2Four = 0x100 +} ; + +enum { + UNOne, + UNTwo +}; + +// Should use NS_ENUM even though it is all power of 2. +typedef NS_ENUM(NSInteger, UIK) { + UIKOne = 1, + UIKTwo = 2, +}; + +typedef NS_ENUM(NSInteger, NSTickMarkPosition) { + NSTickMarkBelow = 0, + NSTickMarkAbove = 1, + NSTickMarkLeft = NSTickMarkAbove, + NSTickMarkRight = NSTickMarkBelow +} ; + +typedef NS_OPTIONS(NSUInteger, UITableStyle) { + UIViewNone = 0x0, + UIViewMargin = 0x1, + UIViewWidth = 0x2, + UIViewRightMargin = 0x3, + UIViewBottomMargin = 0xbadbeef +}; + +typedef NS_OPTIONS(NSUInteger, UIStyle) { + UIView0 = 0, + UIView1 = 0XBADBEEF +}; + +typedef NS_ENUM(NSUInteger, NSBitmapImageFileType) { + NSTIFFFileType, + NSBMPFileType, + NSGIFFileType, + NSJPEGFileType, + NSPNGFileType, + NSJPEG2000FileType +}; + +typedef NS_ENUM(NSUInteger, NSAlertStyle) { + NSWarningAlertStyle = 0, + NSInformationalAlertStyle = 1, + NSCriticalAlertStyle = 2 +}; + +enum { + D_NSTIFFFileType, + D_NSBMPFileType, + D_NSGIFFileType, + D_NSJPEGFileType, + D_NSPNGFileType, + D_NSJPEG2000FileType +}; +typedef NSUInteger D_NSBitmapImageFileType DEPRECATED; + +typedef enum { + D_NSTickMarkBelow = 0, + D_NSTickMarkAbove = 1 +} D_NSTickMarkPosition DEPRECATED; + + +#define NS_ENUM_AVAILABLE(X,Y) + + +typedef NS_OPTIONS(NSUInteger, NSFOptions) { + NSFStrongMemory NS_ENUM_AVAILABLE(10_5, 6_0) = (0UL << 0), + NSFOpaqueMemory NS_ENUM_AVAILABLE(10_5, 6_0) = (2UL << 0), + NSFMallocMemory NS_ENUM_AVAILABLE(10_5, 6_0) = (3UL << 0), + NSFMachVirtualMemory NS_ENUM_AVAILABLE(10_5, 6_0) = (4UL << 0), + NSFWeakMemory NS_ENUM_AVAILABLE(10_8, 6_0) = (5UL << 0), + + NSFObjectPersonality NS_ENUM_AVAILABLE(10_5, 6_0) = (0UL << 8), + NSFOpaquePersonality NS_ENUM_AVAILABLE(10_5, 6_0) = (1UL << 8), + NSFObjectPointerPersonality NS_ENUM_AVAILABLE(10_5, 6_0) = (2UL << 8), + NSFCStringPersonality NS_ENUM_AVAILABLE(10_5, 6_0) = (3UL << 8), + NSFStructPersonality NS_ENUM_AVAILABLE(10_5, 6_0) = (4UL << 8), + NSFIntegerPersonality NS_ENUM_AVAILABLE(10_5, 6_0) = (5UL << 8), + NSFCopyIn NS_ENUM_AVAILABLE(10_5, 6_0) = (1UL << 16), +}; + +typedef NS_ENUM(NSInteger, UIP) { + UIP0One = 0, + UIP0Two = 1, + UIP0Three = 2, + UIP0Four = 10, + UIP0Last = 0x100 +} ; + +typedef NS_OPTIONS(NSUInteger, UIP_3) { + UIPZero = 0x0, + UIPOne = 0x1, + UIPTwo = 0x2, + UIP10 = 0x10, + UIPHundred = 0x100 +} ; + +typedef NS_ENUM(NSInteger, UIP4_3) { + UIP4Zero = 0x0, + UIP4One = 0x1, + UIP4Two = 0x2, + UIP410 = 0x10, + UIP4Hundred = 100 +} ; + +typedef NS_OPTIONS(NSUInteger, UIP5_3) { + UIP5Zero = 0x0, + UIP5Two = 0x2, + UIP510 = 0x3, + UIP5Hundred = 0x4 +} ; + +typedef NS_ENUM(NSInteger, UIP6_3) { + UIP6Zero = 0x0, + UIP6One = 0x1, + UIP6Two = 0x2, + UIP610 = 10, + UIP6Hundred = 0x100 +} ; + +typedef NS_ENUM(NSInteger, UIP7_3) { + UIP7Zero = 0x0, + UIP7One = 1, + UIP7Two = 0x2, + UIP710 = 10, + UIP7Hundred = 100 +} ; + + +typedef NS_ENUM(NSInteger, UIP8_3) { + Random = 0, + Random1 = 2, + Random2 = 4, + Random3 = 0x12345, + Random4 = 0x3444444, + Random5 = 0xbadbeef, + Random6 +} ; + +// rdar://15200602 +#define NS_AVAILABLE_MAC(X) __attribute__((availability(macosx,introduced=X))) +#define NS_ENUM_AVAILABLE_MAC(X) __attribute__((availability(macosx,introduced=X))) + +typedef NS_ENUM(NSInteger, NSModalResponse) { + NSModalResponseStop = (-1000), // Also used as the default response for sheets + NSModalResponseAbort = (-1001), + NSModalResponseContinue = (-1002), +} NS_ENUM_AVAILABLE_MAC(10.9); + +// rdar://15201056 +typedef NSUInteger FarFarAwayOptions; + +// rdar://15200915 +typedef NS_OPTIONS(NSUInteger, FarAwayOptions) { + FarAway1 = 1 << 1, + FarAway2 = 1 << 2 +}; +typedef NS_OPTIONS(NSUInteger, NSWorkspaceLaunchOptions) { + NSWorkspaceLaunchAndPrint = 0x00000002, + NSWorkspaceLaunchWithErrorPresentation = 0x00000040, + NSWorkspaceLaunchInhibitingBackgroundOnly = 0x00000080, + NSWorkspaceLaunchWithoutAddingToRecents = 0x00000100, + NSWorkspaceLaunchWithoutActivation = 0x00000200, + NSWorkspaceLaunchAsync = 0x00010000, + NSWorkspaceLaunchAllowingClassicStartup = 0x00020000, + NSWorkspaceLaunchPreferringClassic = 0x00040000, + NSWorkspaceLaunchNewInstance = 0x00080000, + NSWorkspaceLaunchAndHide = 0x00100000, + NSWorkspaceLaunchAndHideOthers = 0x00200000, + NSWorkspaceLaunchDefault = NSWorkspaceLaunchAsync | + NSWorkspaceLaunchAllowingClassicStartup +}; + +typedef NS_OPTIONS(NSUInteger, NSExcludeOptions) { + NSExcludeQuickDrawElementsIconCreationOption = 1 << 1, + NSExclude10_4ElementsIconCreationOption = 1 << 2 +}; + +typedef NS_OPTIONS(NSUInteger, NSExcludeCreationOption) { + NSExcludeQuickDrawElementsCreationOption = 1 << 1, + NSExclude10_4ElementsCreationOption = 1 << 2 +}; + + +typedef NS_OPTIONS(NSUInteger, NSExcludeIconOptions) { + NSExcludeQuickDrawElementsIconOption = 1 << 1, + NSExclude10_4ElementsIconOption = 1 << 2 +}; + +@interface INTF { + NSExcludeIconOptions I1; + NSExcludeIconOptions I2; +} +@end + +enum { + FarFarAway1 = 1 << 1, + FarFarAway2 = 1 << 2 +}; + +// rdar://15200915 +typedef NS_OPTIONS(NSUInteger, NSWindowOcclusionState) { + NSWindowOcclusionStateVisible = 1UL << 1, +}; + +typedef NS_ENUM(NSUInteger, NSWindowNumberListOptions) { + NSWindowCloseButton, + NSWindowMiniaturizeButton, + NSWindowZoomButton, + NSWindowToolbarButton, + NSWindowDocumentIconButton +}; + +typedef NS_ENUM(NSUInteger, NSSelectionDirection) { + NSDirectSelection = 0, + NSSelectingNext, + NSSelectingPrevious +}; + +// standard window buttons diff --git a/test/ARCMT/objcmt-ns-nonatomic-iosonly.m b/test/ARCMT/objcmt-ns-nonatomic-iosonly.m new file mode 100644 index 0000000..57b2041 --- /dev/null +++ b/test/ARCMT/objcmt-ns-nonatomic-iosonly.m @@ -0,0 +1,236 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fblocks -objcmt-migrate-readwrite-property -objcmt-ns-nonatomic-iosonly -objcmt-migrate-readonly-property -objcmt-atomic-property -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 +// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result +// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result + +#define WEBKIT_OBJC_METHOD_ANNOTATION(ANNOTATION) ANNOTATION +#define WEAK_IMPORT_ATTRIBUTE __attribute__((objc_arc_weak_reference_unavailable)) +#define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER +#define DEPRECATED __attribute__((deprecated)) + +// rdar://15442742 +#if TARGET_OS_IPHONE + #define NS_NONATOMIC_IOSONLY nonatomic +#else + #define NS_NONATOMIC_IOSONLY atomic +#endif + +typedef char BOOL; +@class NSString; +@protocol NSCopying @end + +@interface NSObject <NSCopying> +@end + +@interface NSDictionary : NSObject +@end + +@interface I : NSObject { + int ivarVal; +} +- (void) setWeakProp : (NSString *__weak)Val; +- (NSString *__weak) WeakProp; + +- (NSString *) StrongProp; +- (void) setStrongProp : (NSString *)Val; + +- (NSString *) UnavailProp __attribute__((unavailable)); +- (void) setUnavailProp : (NSString *)Val; + +- (NSString *) UnavailProp1 __attribute__((unavailable)); +- (void) setUnavailProp1 : (NSString *)Val __attribute__((unavailable)); + +- (NSString *) UnavailProp2; +- (void) setUnavailProp2 : (NSString *)Val __attribute__((unavailable)); + +- (NSDictionary*) undoAction; +- (void) setUndoAction: (NSDictionary*)Arg; +@end + +@implementation I +@end + +@class NSArray; + +@interface MyClass2 { +@private + NSArray *_names1; + NSArray *_names2; + NSArray *_names3; + NSArray *_names4; +} +- (void)setNames1:(NSArray *)names; +- (void)setNames4:(__strong NSArray *)names; +- (void)setNames3:(__strong NSArray *)names; +- (void)setNames2:(NSArray *)names; +- (NSArray *) names2; +- (NSArray *)names3; +- (__strong NSArray *)names4; +- (NSArray *) names1; +@end + +// Properties that contain the name "delegate" or "dataSource", +// or have exact name "target" have unsafe_unretained attribute. +@interface NSInvocation +- (id)target; +- (void)setTarget:(id)target; + +- (id) dataSource; + +- (id)xxxdelegateYYY; +- (void)setXxxdelegateYYY:(id)delegate; + +- (void)setDataSource:(id)source; + +- (id)MYtarget; +- (void)setMYtarget: (id)target; + +- (id)targetX; +- (void)setTargetX: (id)t; + +- (int)value; +- (void)setValue: (int)val; + +-(BOOL) isContinuous; +-(void) setContinuous:(BOOL)value; + +- (id) isAnObject; +- (void)setAnObject : (id) object; + +- (BOOL) isinValid; +- (void) setInValid : (BOOL) arg; + +- (void) Nothing; +- (int) Length; +- (id) object; ++ (double) D; +- (void *)JSObject WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER); +- (BOOL)isIgnoringInteractionEvents; + +- (NSString *)getStringValue; +- (BOOL)getCounterValue; +- (void)setStringValue:(NSString *)stringValue AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +- (NSDictionary *)getns_dixtionary; + +- (BOOL)is3bar; // watch out +- (NSString *)get3foo; // watch out + +- (BOOL) getM; +- (BOOL) getMA; +- (BOOL) getALL; +- (BOOL) getMANY; +- (BOOL) getSome; +@end + + +@interface NSInvocation(CAT) +- (id)target; +- (void)setTarget:(id)target; + +- (id) dataSource; + +- (id)xxxdelegateYYY; +- (void)setXxxdelegateYYY:(id)delegate; + +- (void)setDataSource:(id)source; + +- (id)MYtarget; +- (void)setMYtarget: (id)target; + +- (id)targetX; +- (void)setTargetX: (id)t; + +- (int)value; +- (void)setValue: (int)val; + +-(BOOL) isContinuous; +-(void) setContinuous:(BOOL)value; + +- (id) isAnObject; +- (void)setAnObject : (id) object; + +- (BOOL) isinValid; +- (void) setInValid : (BOOL) arg; + +- (void) Nothing; +- (int) Length; +- (id) object; ++ (double) D; + +- (BOOL)is3bar; // watch out +- (NSString *)get3foo; // watch out + +- (BOOL) getM; +- (BOOL) getMA; +- (BOOL) getALL; +- (BOOL) getMANY; +- (BOOL) getSome; +@end + +DEPRECATED +@interface I_DEP +- (BOOL) isinValid; +- (void) setInValid : (BOOL) arg; +@end + +@interface AnotherOne +- (BOOL) isinValid DEPRECATED; +- (void) setInValid : (BOOL) arg; +- (id)MYtarget; +- (void)setMYtarget: (id)target DEPRECATED; +- (BOOL) getM DEPRECATED; + +- (id)xxxdelegateYYY DEPRECATED; +- (void)setXxxdelegateYYY:(id)delegate DEPRECATED; +@end + +// rdar://14987909 +#define NS_AVAILABLE __attribute__((availability(macosx,introduced=10.0))) +#define NORETURN __attribute__((noreturn)) +#define ALIGNED __attribute__((aligned(16))) + +@interface NSURL +// Do not infer a property. +- (NSURL *)appStoreReceiptURL NS_AVAILABLE; +- (void) setAppStoreReceiptURL : (NSURL *)object; + +- (NSURL *)appStoreReceiptURLX NS_AVAILABLE; +- (void) setAppStoreReceiptURLX : (NSURL *)object NS_AVAILABLE; + +// Do not infer a property. +- (NSURL *)appStoreReceiptURLY ; +- (void) setAppStoreReceiptURLY : (NSURL *)object NS_AVAILABLE; + +- (id)OkToInfer NS_AVAILABLE; + +// Do not infer a property. +- (NSURL *)appStoreReceiptURLZ ; +- (void) setAppStoreReceiptURLZ : (NSURL *)object NS_AVAILABLE; + +// Do not infer a property. +- (id) t1 NORETURN NS_AVAILABLE; +- (void) setT1 : (id) arg NS_AVAILABLE; + +- (id)method1 ALIGNED NS_AVAILABLE; +- (void) setMethod1 : (id) object NS_AVAILABLE ALIGNED; + +- (NSURL *)init; // No Change ++ (id)alloc; // No Change + +- (BOOL)is1stClass; // Not a valid property +- (BOOL)isClass; // This is a valid property 'class' is not a keyword in ObjC +- (BOOL)isDouble; // Not a valid property + +@end + +// rdar://15082818 +@class NSMutableDictionary; + +@interface NSArray +- (id (^)(id, NSArray *, NSMutableDictionary *)) expressionBlock; +- (id (^)(id, NSArray *, NSMutableDictionary *)) MyBlock; +- (void) setMyBlock : (id (^)(id, NSArray *, NSMutableDictionary *)) bl; +- (id (*)(id, NSArray *, NSMutableDictionary *)) expressionFuncptr; +- (id (*)(id, NSArray *, NSMutableDictionary *)) MyFuncptr; +- (void) setMyFuncptr : (id (*)(id, NSArray *, NSMutableDictionary *)) bl; +@end diff --git a/test/ARCMT/objcmt-ns-nonatomic-iosonly.m.result b/test/ARCMT/objcmt-ns-nonatomic-iosonly.m.result new file mode 100644 index 0000000..804142e --- /dev/null +++ b/test/ARCMT/objcmt-ns-nonatomic-iosonly.m.result @@ -0,0 +1,209 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fblocks -objcmt-migrate-readwrite-property -objcmt-ns-nonatomic-iosonly -objcmt-migrate-readonly-property -objcmt-atomic-property -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 +// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result +// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result + +#define WEBKIT_OBJC_METHOD_ANNOTATION(ANNOTATION) ANNOTATION +#define WEAK_IMPORT_ATTRIBUTE __attribute__((objc_arc_weak_reference_unavailable)) +#define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER +#define DEPRECATED __attribute__((deprecated)) + +// rdar://15442742 +#if TARGET_OS_IPHONE + #define NS_NONATOMIC_IOSONLY nonatomic +#else + #define NS_NONATOMIC_IOSONLY atomic +#endif + +typedef char BOOL; +@class NSString; +@protocol NSCopying @end + +@interface NSObject <NSCopying> +@end + +@interface NSDictionary : NSObject +@end + +@interface I : NSObject { + int ivarVal; +} +@property (NS_NONATOMIC_IOSONLY, weak) NSString *WeakProp; + +@property (NS_NONATOMIC_IOSONLY, retain) NSString *StrongProp; + +@property (NS_NONATOMIC_IOSONLY, retain) NSString *UnavailProp __attribute__((unavailable)); +- (void) setUnavailProp : (NSString *)Val; + +@property (NS_NONATOMIC_IOSONLY, retain) NSString *UnavailProp1 __attribute__((unavailable)); + +@property (NS_NONATOMIC_IOSONLY, retain) NSString *UnavailProp2; +- (void) setUnavailProp2 : (NSString *)Val __attribute__((unavailable)); + +@property (NS_NONATOMIC_IOSONLY, copy) NSDictionary *undoAction; +@end + +@implementation I +@end + +@class NSArray; + +@interface MyClass2 { +@private + NSArray *_names1; + NSArray *_names2; + NSArray *_names3; + NSArray *_names4; +} +@property (NS_NONATOMIC_IOSONLY, retain) NSArray *names2; +@property (NS_NONATOMIC_IOSONLY, retain) NSArray *names3; +@property (NS_NONATOMIC_IOSONLY, retain) NSArray *names4; +@property (NS_NONATOMIC_IOSONLY, retain) NSArray *names1; +@end + +// Properties that contain the name "delegate" or "dataSource", +// or have exact name "target" have unsafe_unretained attribute. +@interface NSInvocation +@property (NS_NONATOMIC_IOSONLY, assign) id target; + +@property (NS_NONATOMIC_IOSONLY, assign) id dataSource; + +@property (NS_NONATOMIC_IOSONLY, assign) id xxxdelegateYYY; + + +@property (NS_NONATOMIC_IOSONLY, retain) id MYtarget; + +@property (NS_NONATOMIC_IOSONLY, retain) id targetX; + +@property (NS_NONATOMIC_IOSONLY) int value; + +@property (NS_NONATOMIC_IOSONLY, getter=isContinuous) BOOL continuous; + +- (id) isAnObject; +- (void)setAnObject : (id) object; + +@property (NS_NONATOMIC_IOSONLY, getter=isinValid, readonly) BOOL inValid; +- (void) setInValid : (BOOL) arg; + +- (void) Nothing; +@property (NS_NONATOMIC_IOSONLY, readonly) int Length; +@property (NS_NONATOMIC_IOSONLY, readonly, retain) id object; ++ (double) D; +@property (NS_NONATOMIC_IOSONLY, readonly) void *JSObject WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER); +@property (NS_NONATOMIC_IOSONLY, getter=isIgnoringInteractionEvents, readonly) BOOL ignoringInteractionEvents; + +@property (NS_NONATOMIC_IOSONLY, getter=getStringValue, retain) NSString *stringValue; +@property (NS_NONATOMIC_IOSONLY, getter=getCounterValue, readonly) BOOL counterValue; +@property (NS_NONATOMIC_IOSONLY, getter=getns_dixtionary, readonly, retain) NSDictionary *ns_dixtionary; + +- (BOOL)is3bar; // watch out +- (NSString *)get3foo; // watch out + +@property (NS_NONATOMIC_IOSONLY, getter=getM, readonly) BOOL m; +@property (NS_NONATOMIC_IOSONLY, getter=getMA, readonly) BOOL MA; +@property (NS_NONATOMIC_IOSONLY, getter=getALL, readonly) BOOL ALL; +@property (NS_NONATOMIC_IOSONLY, getter=getMANY, readonly) BOOL MANY; +@property (NS_NONATOMIC_IOSONLY, getter=getSome, readonly) BOOL some; +@end + + +@interface NSInvocation(CAT) +@property (NS_NONATOMIC_IOSONLY, assign) id target; + +@property (NS_NONATOMIC_IOSONLY, assign) id dataSource; + +@property (NS_NONATOMIC_IOSONLY, assign) id xxxdelegateYYY; + + +@property (NS_NONATOMIC_IOSONLY, retain) id MYtarget; + +@property (NS_NONATOMIC_IOSONLY, retain) id targetX; + +@property (NS_NONATOMIC_IOSONLY) int value; + +@property (NS_NONATOMIC_IOSONLY, getter=isContinuous) BOOL continuous; + +- (id) isAnObject; +- (void)setAnObject : (id) object; + +@property (NS_NONATOMIC_IOSONLY, getter=isinValid, readonly) BOOL inValid; +- (void) setInValid : (BOOL) arg; + +- (void) Nothing; +@property (NS_NONATOMIC_IOSONLY, readonly) int Length; +@property (NS_NONATOMIC_IOSONLY, readonly, retain) id object; ++ (double) D; + +- (BOOL)is3bar; // watch out +- (NSString *)get3foo; // watch out + +@property (NS_NONATOMIC_IOSONLY, getter=getM, readonly) BOOL m; +@property (NS_NONATOMIC_IOSONLY, getter=getMA, readonly) BOOL MA; +@property (NS_NONATOMIC_IOSONLY, getter=getALL, readonly) BOOL ALL; +@property (NS_NONATOMIC_IOSONLY, getter=getMANY, readonly) BOOL MANY; +@property (NS_NONATOMIC_IOSONLY, getter=getSome, readonly) BOOL some; +@end + +DEPRECATED +@interface I_DEP +- (BOOL) isinValid; +- (void) setInValid : (BOOL) arg; +@end + +@interface AnotherOne +- (BOOL) isinValid DEPRECATED; +- (void) setInValid : (BOOL) arg; +- (id)MYtarget; +- (void)setMYtarget: (id)target DEPRECATED; +- (BOOL) getM DEPRECATED; + +- (id)xxxdelegateYYY DEPRECATED; +- (void)setXxxdelegateYYY:(id)delegate DEPRECATED; +@end + +// rdar://14987909 +#define NS_AVAILABLE __attribute__((availability(macosx,introduced=10.0))) +#define NORETURN __attribute__((noreturn)) +#define ALIGNED __attribute__((aligned(16))) + +@interface NSURL +// Do not infer a property. +@property (NS_NONATOMIC_IOSONLY, retain) NSURL *appStoreReceiptURL NS_AVAILABLE; +- (void) setAppStoreReceiptURL : (NSURL *)object; + +@property (NS_NONATOMIC_IOSONLY, retain) NSURL *appStoreReceiptURLX NS_AVAILABLE; + +// Do not infer a property. +@property (NS_NONATOMIC_IOSONLY, retain) NSURL *appStoreReceiptURLY ; +- (void) setAppStoreReceiptURLY : (NSURL *)object NS_AVAILABLE; + +@property (NS_NONATOMIC_IOSONLY, readonly, retain) id OkToInfer NS_AVAILABLE; + +// Do not infer a property. +@property (NS_NONATOMIC_IOSONLY, retain) NSURL *appStoreReceiptURLZ ; +- (void) setAppStoreReceiptURLZ : (NSURL *)object NS_AVAILABLE; + +// Do not infer a property. +- (id) t1 NORETURN NS_AVAILABLE; +- (void) setT1 : (id) arg NS_AVAILABLE; + +@property (NS_NONATOMIC_IOSONLY, retain) id method1 ALIGNED NS_AVAILABLE; + +- (NSURL *)init; // No Change ++ (id)alloc; // No Change + +- (BOOL)is1stClass; // Not a valid property +@property (NS_NONATOMIC_IOSONLY, getter=isClass, readonly) BOOL class; // This is a valid property 'class' is not a keyword in ObjC +- (BOOL)isDouble; // Not a valid property + +@end + +// rdar://15082818 +@class NSMutableDictionary; + +@interface NSArray +@property (NS_NONATOMIC_IOSONLY, readonly, copy) id (^expressionBlock)(id, NSArray *, NSMutableDictionary *); +@property (NS_NONATOMIC_IOSONLY, copy) id (^MyBlock)(id, NSArray *, NSMutableDictionary *); +@property (NS_NONATOMIC_IOSONLY, readonly) id (*expressionFuncptr)(id, NSArray *, NSMutableDictionary *); +@property (NS_NONATOMIC_IOSONLY) id (*MyFuncptr)(id, NSArray *, NSMutableDictionary *); +@end diff --git a/test/ARCMT/objcmt-ns-returns-inner-pointer.m b/test/ARCMT/objcmt-ns-returns-inner-pointer.m new file mode 100644 index 0000000..bff7d80 --- /dev/null +++ b/test/ARCMT/objcmt-ns-returns-inner-pointer.m @@ -0,0 +1,129 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -objcmt-returns-innerpointer-property -objcmt-migrate-annotation -objcmt-migrate-readwrite-property -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 +// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result + +#ifndef NS_RETURNS_INNER_POINTER // defined in iOS 6 for sure +#define NS_RETURNS_INNER_POINTER __attribute__((objc_returns_inner_pointer)) +#endif + +#define CF_IMPLICIT_BRIDGING_ENABLED _Pragma("clang arc_cf_code_audited begin") + +#define CF_IMPLICIT_BRIDGING_DISABLED _Pragma("clang arc_cf_code_audited end") + +#if __has_feature(attribute_ns_returns_retained) +#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained)) +#endif +#if __has_feature(attribute_cf_returns_retained) +#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained)) +#endif +#if __has_feature(attribute_ns_returns_not_retained) +#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained)) +#endif +#if __has_feature(attribute_cf_returns_not_retained) +#define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained)) +#endif +#if __has_feature(attribute_ns_consumes_self) +#define NS_CONSUMES_SELF __attribute__((ns_consumes_self)) +#endif +#if __has_feature(attribute_ns_consumed) +#define NS_CONSUMED __attribute__((ns_consumed)) +#endif +#if __has_feature(attribute_cf_consumed) +#define CF_CONSUMED __attribute__((cf_consumed)) +#endif +#if __has_attribute(ns_returns_autoreleased) +#define NS_RETURNS_AUTORELEASED __attribute__((ns_returns_autoreleased)) +#endif + +#define NS_AVAILABLE __attribute__((availability(macosx,introduced=10.0))) + +CF_IMPLICIT_BRIDGING_ENABLED + +typedef unsigned long CFTypeID; +typedef unsigned long CFOptionFlags; +typedef unsigned long CFHashCode; + +typedef signed long CFIndex; /*AnyObj*/ +typedef const struct __CFArray * CFArrayRef; +typedef struct { + CFIndex location; + CFIndex length; +} CFRange; + +typedef void (*CFArrayApplierFunction)(const void *value, void *context); + +typedef enum CFComparisonResult : CFIndex CFComparisonResult; enum CFComparisonResult : CFIndex { + kCFCompareLessThan = -1L, + kCFCompareEqualTo = 0, + kCFCompareGreaterThan = 1 +}; + + +typedef CFComparisonResult (*CFComparatorFunction)(const void *val1, const void *val2, void *context); + +typedef struct __CFArray * CFMutableArrayRef; + +typedef const struct __CFAttributedString *CFAttributedStringRef; +typedef struct __CFAttributedString *CFMutableAttributedStringRef; + +typedef const struct __CFAllocator * CFAllocatorRef; + +typedef const struct __CFString * CFStringRef; +typedef struct __CFString * CFMutableStringRef; + +typedef const struct __CFDictionary * CFDictionaryRef; +typedef struct __CFDictionary * CFMutableDictionaryRef; + +typedef struct CGImage *CGImageRef; + +typedef struct OpaqueJSValue* JSObjectRef; + +typedef JSObjectRef TTJSObjectRef; +typedef unsigned int NSUInteger; + +CF_IMPLICIT_BRIDGING_DISABLED + +@interface I +- (void*) ReturnsInnerPointer; +- (int*) AlreadyReturnsInnerPointer NS_RETURNS_INNER_POINTER; +@end + +@interface UIImage +- (CGImageRef)CGImage; +@end + +@interface NSData +- (void *)bytes; +- (void **) ptr_bytes __attribute__((availability(macosx,unavailable))); +@end + +@interface NSMutableData +- (void *)mutableBytes __attribute__((deprecated)) __attribute__((unavailable)); +@end + +@interface JS +- (JSObjectRef)JSObject; +- (TTJSObjectRef)JSObject1; +- (JSObjectRef*)JSObject2; +@end + +// rdar://15044991 +typedef void *SecTrustRef; + +@interface NSURLProtectionSpace +@property (readonly) SecTrustRef serverTrust NS_AVAILABLE; +- (void *) FOO NS_AVAILABLE; +@property (readonly) void * mitTrust NS_AVAILABLE; + +@property (readonly) void * mittiTrust; + +@property (readonly) SecTrustRef XserverTrust; + +- (SecTrustRef) FOO1 NS_AVAILABLE; + ++ (const NSURLProtectionSpace *)ProtectionSpace; + +// pointer personality functions +@property NSUInteger (*hashFunction)(const void *item, NSUInteger (*size)(const void *item)); +@end diff --git a/test/ARCMT/objcmt-ns-returns-inner-pointer.m.result b/test/ARCMT/objcmt-ns-returns-inner-pointer.m.result new file mode 100644 index 0000000..8048e06 --- /dev/null +++ b/test/ARCMT/objcmt-ns-returns-inner-pointer.m.result @@ -0,0 +1,129 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -objcmt-returns-innerpointer-property -objcmt-migrate-annotation -objcmt-migrate-readwrite-property -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 +// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result + +#ifndef NS_RETURNS_INNER_POINTER // defined in iOS 6 for sure +#define NS_RETURNS_INNER_POINTER __attribute__((objc_returns_inner_pointer)) +#endif + +#define CF_IMPLICIT_BRIDGING_ENABLED _Pragma("clang arc_cf_code_audited begin") + +#define CF_IMPLICIT_BRIDGING_DISABLED _Pragma("clang arc_cf_code_audited end") + +#if __has_feature(attribute_ns_returns_retained) +#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained)) +#endif +#if __has_feature(attribute_cf_returns_retained) +#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained)) +#endif +#if __has_feature(attribute_ns_returns_not_retained) +#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained)) +#endif +#if __has_feature(attribute_cf_returns_not_retained) +#define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained)) +#endif +#if __has_feature(attribute_ns_consumes_self) +#define NS_CONSUMES_SELF __attribute__((ns_consumes_self)) +#endif +#if __has_feature(attribute_ns_consumed) +#define NS_CONSUMED __attribute__((ns_consumed)) +#endif +#if __has_feature(attribute_cf_consumed) +#define CF_CONSUMED __attribute__((cf_consumed)) +#endif +#if __has_attribute(ns_returns_autoreleased) +#define NS_RETURNS_AUTORELEASED __attribute__((ns_returns_autoreleased)) +#endif + +#define NS_AVAILABLE __attribute__((availability(macosx,introduced=10.0))) + +CF_IMPLICIT_BRIDGING_ENABLED + +typedef unsigned long CFTypeID; +typedef unsigned long CFOptionFlags; +typedef unsigned long CFHashCode; + +typedef signed long CFIndex; /*AnyObj*/ +typedef const struct __CFArray * CFArrayRef; +typedef struct { + CFIndex location; + CFIndex length; +} CFRange; + +typedef void (*CFArrayApplierFunction)(const void *value, void *context); + +typedef enum CFComparisonResult : CFIndex CFComparisonResult; enum CFComparisonResult : CFIndex { + kCFCompareLessThan = -1L, + kCFCompareEqualTo = 0, + kCFCompareGreaterThan = 1 +}; + + +typedef CFComparisonResult (*CFComparatorFunction)(const void *val1, const void *val2, void *context); + +typedef struct __CFArray * CFMutableArrayRef; + +typedef const struct __CFAttributedString *CFAttributedStringRef; +typedef struct __CFAttributedString *CFMutableAttributedStringRef; + +typedef const struct __CFAllocator * CFAllocatorRef; + +typedef const struct __CFString * CFStringRef; +typedef struct __CFString * CFMutableStringRef; + +typedef const struct __CFDictionary * CFDictionaryRef; +typedef struct __CFDictionary * CFMutableDictionaryRef; + +typedef struct CGImage *CGImageRef; + +typedef struct OpaqueJSValue* JSObjectRef; + +typedef JSObjectRef TTJSObjectRef; +typedef unsigned int NSUInteger; + +CF_IMPLICIT_BRIDGING_DISABLED + +@interface I +- (void*) ReturnsInnerPointer NS_RETURNS_INNER_POINTER; +- (int*) AlreadyReturnsInnerPointer NS_RETURNS_INNER_POINTER; +@end + +@interface UIImage +- (CGImageRef)CGImage CF_RETURNS_NOT_RETAINED; +@end + +@interface NSData +- (void *)bytes NS_RETURNS_INNER_POINTER; +- (void **) ptr_bytes __attribute__((availability(macosx,unavailable))) NS_RETURNS_INNER_POINTER; +@end + +@interface NSMutableData +- (void *)mutableBytes __attribute__((deprecated)) __attribute__((unavailable)) NS_RETURNS_INNER_POINTER; +@end + +@interface JS +- (JSObjectRef)JSObject; +- (TTJSObjectRef)JSObject1; +- (JSObjectRef*)JSObject2 NS_RETURNS_INNER_POINTER; +@end + +// rdar://15044991 +typedef void *SecTrustRef; + +@interface NSURLProtectionSpace +@property (readonly) SecTrustRef NS_RETURNS_INNER_POINTER serverTrust NS_AVAILABLE; +- (void *) FOO NS_AVAILABLE NS_RETURNS_INNER_POINTER; +@property (readonly) void * NS_RETURNS_INNER_POINTER mitTrust NS_AVAILABLE; + +@property (readonly) void * NS_RETURNS_INNER_POINTER mittiTrust; + +@property (readonly) SecTrustRef NS_RETURNS_INNER_POINTER XserverTrust; + +- (SecTrustRef) FOO1 NS_AVAILABLE NS_RETURNS_INNER_POINTER; + ++ (const NSURLProtectionSpace *)ProtectionSpace; + +// pointer personality functions +@property NSUInteger (*hashFunction)(const void *item, NSUInteger (*size)(const void *item)); +@end diff --git a/test/ARCMT/objcmt-property-availability.m b/test/ARCMT/objcmt-property-availability.m new file mode 100644 index 0000000..d499221 --- /dev/null +++ b/test/ARCMT/objcmt-property-availability.m @@ -0,0 +1,46 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -objcmt-migrate-readwrite-property -objcmt-migrate-readonly-property -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 +// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result +// rdar://15300059 + + +#define __NSi_7_0 introduced=7.0 +#define __NSi_6_0 introduced=6.0 + +#define CF_AVAILABLE(_mac, _ios) __attribute__((availability(ios,__NSi_##_ios))) +#define CF_AVAILABLE_MAC(_mac) __attribute__((availability(macosx,__NSi_##_mac))) +#define CF_AVAILABLE_IOS(_ios) __attribute__((availability(macosx,unavailable))) + +#define NS_AVAILABLE(_mac, _ios) CF_AVAILABLE(_mac, _ios) +#define NS_AVAILABLE_MAC(_mac) CF_AVAILABLE_MAC(_mac) +#define NS_AVAILABLE_IOS(_ios) CF_AVAILABLE_IOS(_ios) + +#define UNAVAILABLE __attribute__((unavailable("not available in automatic reference counting mode"))) + +@interface MKMapItem +- (MKMapItem *)source NS_AVAILABLE(10_9, 6_0); +- (void)setSource:(MKMapItem *)source NS_AVAILABLE(10_9, 7_0); + +- (void)setDest:(MKMapItem *)source NS_AVAILABLE(10_9, 6_0); +- (MKMapItem *)dest NS_AVAILABLE(10_9, 6_0); + +- (MKMapItem *)final; +- (void)setFinal:(MKMapItem *)source; + +- (MKMapItem *)total NS_AVAILABLE(10_9, 6_0); +- (void)setTotal:(MKMapItem *)source; + +- (MKMapItem *)comp NS_AVAILABLE(10_9, 6_0); +- (void)setComp:(MKMapItem *)source UNAVAILABLE; + +- (MKMapItem *)tally UNAVAILABLE NS_AVAILABLE(10_9, 6_0); +- (void)setTally:(MKMapItem *)source UNAVAILABLE NS_AVAILABLE(10_9, 6_0); + +- (MKMapItem *)itally NS_AVAILABLE(10_9, 6_0); +- (void)setItally:(MKMapItem *)source UNAVAILABLE NS_AVAILABLE(10_9, 6_0); + +- (MKMapItem *)normal UNAVAILABLE; +- (void)setNormal:(MKMapItem *)source UNAVAILABLE NS_AVAILABLE(10_9, 6_0); +@end + diff --git a/test/ARCMT/objcmt-property-availability.m.result b/test/ARCMT/objcmt-property-availability.m.result new file mode 100644 index 0000000..681f9a9 --- /dev/null +++ b/test/ARCMT/objcmt-property-availability.m.result @@ -0,0 +1,43 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -objcmt-migrate-readwrite-property -objcmt-migrate-readonly-property -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 +// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result +// rdar://15300059 + + +#define __NSi_7_0 introduced=7.0 +#define __NSi_6_0 introduced=6.0 + +#define CF_AVAILABLE(_mac, _ios) __attribute__((availability(ios,__NSi_##_ios))) +#define CF_AVAILABLE_MAC(_mac) __attribute__((availability(macosx,__NSi_##_mac))) +#define CF_AVAILABLE_IOS(_ios) __attribute__((availability(macosx,unavailable))) + +#define NS_AVAILABLE(_mac, _ios) CF_AVAILABLE(_mac, _ios) +#define NS_AVAILABLE_MAC(_mac) CF_AVAILABLE_MAC(_mac) +#define NS_AVAILABLE_IOS(_ios) CF_AVAILABLE_IOS(_ios) + +#define UNAVAILABLE __attribute__((unavailable("not available in automatic reference counting mode"))) + +@interface MKMapItem +@property (nonatomic, retain) MKMapItem *source NS_AVAILABLE(10_9, 6_0); +- (void)setSource:(MKMapItem *)source NS_AVAILABLE(10_9, 7_0); + +@property (nonatomic, retain) MKMapItem *dest NS_AVAILABLE(10_9, 6_0); + +@property (nonatomic, retain) MKMapItem *final; + +@property (nonatomic, retain) MKMapItem *total NS_AVAILABLE(10_9, 6_0); +- (void)setTotal:(MKMapItem *)source; + +- (MKMapItem *)comp NS_AVAILABLE(10_9, 6_0); +- (void)setComp:(MKMapItem *)source UNAVAILABLE; + +@property (nonatomic, retain) MKMapItem *tally UNAVAILABLE NS_AVAILABLE(10_9, 6_0); + +- (MKMapItem *)itally NS_AVAILABLE(10_9, 6_0); +- (void)setItally:(MKMapItem *)source UNAVAILABLE NS_AVAILABLE(10_9, 6_0); + +- (MKMapItem *)normal UNAVAILABLE; +- (void)setNormal:(MKMapItem *)source UNAVAILABLE NS_AVAILABLE(10_9, 6_0); +@end + diff --git a/test/ARCMT/objcmt-property.m b/test/ARCMT/objcmt-property.m new file mode 100644 index 0000000..3b77aad --- /dev/null +++ b/test/ARCMT/objcmt-property.m @@ -0,0 +1,237 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fblocks -objcmt-migrate-readwrite-property -objcmt-migrate-readonly-property -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 +// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result +// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result + +#define WEBKIT_OBJC_METHOD_ANNOTATION(ANNOTATION) ANNOTATION +#define WEAK_IMPORT_ATTRIBUTE __attribute__((objc_arc_weak_reference_unavailable)) +#define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER +#define DEPRECATED __attribute__((deprecated)) + +typedef char BOOL; +@class NSString; +@protocol NSCopying @end + +@interface NSObject <NSCopying> +@end + +@interface NSDictionary : NSObject +@end + +@interface I : NSObject { + int ivarVal; +} +- (void) setWeakProp : (NSString *__weak)Val; +- (NSString *__weak) WeakProp; + +- (NSString *) StrongProp; +- (void) setStrongProp : (NSString *)Val; + +- (NSString *) UnavailProp __attribute__((unavailable)); +- (void) setUnavailProp : (NSString *)Val; + +- (NSString *) UnavailProp1 __attribute__((unavailable)); +- (void) setUnavailProp1 : (NSString *)Val __attribute__((unavailable)); + +- (NSString *) UnavailProp2; +- (void) setUnavailProp2 : (NSString *)Val __attribute__((unavailable)); + +- (NSDictionary*) undoAction; +- (void) setUndoAction: (NSDictionary*)Arg; +@end + +@implementation I +@end + +@class NSArray; + +@interface MyClass2 { +@private + NSArray *_names1; + NSArray *_names2; + NSArray *_names3; + NSArray *_names4; +} +- (void)setNames1:(NSArray *)names; +- (void)setNames4:(__strong NSArray *)names; +- (void)setNames3:(__strong NSArray *)names; +- (void)setNames2:(NSArray *)names; +- (NSArray *) names2; +- (NSArray *)names3; +- (__strong NSArray *)names4; +- (NSArray *) names1; +@end + +// Properties that contain the name "delegate" or "dataSource", +// or have exact name "target" have unsafe_unretained attribute. +@interface NSInvocation +- (id)target; +- (void)setTarget:(id)target; + +- (id) dataSource; + +- (id)xxxdelegateYYY; +- (void)setXxxdelegateYYY:(id)delegate; + +- (void)setDataSource:(id)source; + +- (id)MYtarget; +- (void)setMYtarget: (id)target; + +- (id)targetX; +- (void)setTargetX: (id)t; + +- (int)value; +- (void)setValue: (int)val; + +-(BOOL) isContinuous; +-(void) setContinuous:(BOOL)value; + +- (id) isAnObject; +- (void)setAnObject : (id) object; + +- (BOOL) isinValid; +- (void) setInValid : (BOOL) arg; + +- (void) Nothing; +- (int) Length; +- (id) object; ++ (double) D; +- (void *)JSObject WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER); +- (BOOL)isIgnoringInteractionEvents; + +- (NSString *)getStringValue; +- (BOOL)getCounterValue; +- (void)setStringValue:(NSString *)stringValue AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; +- (NSDictionary *)getns_dixtionary; + +- (BOOL)is3bar; // watch out +- (NSString *)get3foo; // watch out + +- (BOOL) getM; +- (BOOL) getMA; +- (BOOL) getALL; +- (BOOL) getMANY; +- (BOOL) getSome; +@end + + +@interface NSInvocation(CAT) +- (id)target; +- (void)setTarget:(id)target; + +- (id) dataSource; + +- (id)xxxdelegateYYY; +- (void)setXxxdelegateYYY:(id)delegate; + +- (void)setDataSource:(id)source; + +- (id)MYtarget; +- (void)setMYtarget: (id)target; + +- (id)targetX; +- (void)setTargetX: (id)t; + +- (int)value; +- (void)setValue: (int)val; + +-(BOOL) isContinuous; +-(void) setContinuous:(BOOL)value; + +- (id) isAnObject; +- (void)setAnObject : (id) object; + +- (BOOL) isinValid; +- (void) setInValid : (BOOL) arg; + +- (void) Nothing; +- (int) Length; +- (id) object; ++ (double) D; + +- (BOOL)is3bar; // watch out +- (NSString *)get3foo; // watch out + +- (BOOL) getM; +- (BOOL) getMA; +- (BOOL) getALL; +- (BOOL) getMANY; +- (BOOL) getSome; +@end + +DEPRECATED +@interface I_DEP +- (BOOL) isinValid; +- (void) setInValid : (BOOL) arg; +@end + +@interface AnotherOne +- (BOOL) isinValid DEPRECATED; +- (void) setInValid : (BOOL) arg; +- (id)MYtarget; +- (void)setMYtarget: (id)target DEPRECATED; +- (BOOL) getM DEPRECATED; + +- (id)xxxdelegateYYY DEPRECATED; +- (void)setXxxdelegateYYY:(id)delegate DEPRECATED; +@end + +// rdar://14987909 +#define NS_AVAILABLE __attribute__((availability(macosx,introduced=10.0))) +#define NORETURN __attribute__((noreturn)) +#define ALIGNED __attribute__((aligned(16))) + +@interface NSURL +// Do not infer a property. +- (NSURL *)appStoreReceiptURL NS_AVAILABLE; +- (void) setAppStoreReceiptURL : (NSURL *)object; + +- (NSURL *)appStoreReceiptURLX NS_AVAILABLE; +- (void) setAppStoreReceiptURLX : (NSURL *)object NS_AVAILABLE; + +// Do not infer a property. +- (NSURL *)appStoreReceiptURLY ; +- (void) setAppStoreReceiptURLY : (NSURL *)object NS_AVAILABLE; + +- (id)OkToInfer NS_AVAILABLE; + +// Do not infer a property. +- (NSURL *)appStoreReceiptURLZ ; +- (void) setAppStoreReceiptURLZ : (NSURL *)object NS_AVAILABLE; + +// Do not infer a property. +- (id) t1 NORETURN NS_AVAILABLE; +- (void) setT1 : (id) arg NS_AVAILABLE; + +- (id)method1 ALIGNED NS_AVAILABLE; +- (void) setMethod1 : (id) object NS_AVAILABLE ALIGNED; + +- (NSURL *)init; // No Change ++ (id)alloc; // No Change + +- (BOOL)is1stClass; // Not a valid property +- (BOOL)isClass; // This is a valid property 'class' is not a keyword in ObjC +- (BOOL)isDouble; // Not a valid property + +@end + +// rdar://15082818 +@class NSMutableDictionary; + +@interface NSArray +- (id (^)(id, NSArray *, NSMutableDictionary *)) expressionBlock; +- (id (^)(id, NSArray *, NSMutableDictionary *)) MyBlock; +- (void) setMyBlock : (id (^)(id, NSArray *, NSMutableDictionary *)) bl; +- (id (*)(id, NSArray *, NSMutableDictionary *)) expressionFuncptr; +- (id (*)(id, NSArray *, NSMutableDictionary *)) MyFuncptr; +- (void) setMyFuncptr : (id (*)(id, NSArray *, NSMutableDictionary *)) bl; +@end + +// rdar://15231241 +@interface rdar15231241 +@property (nonatomic, readonly) double Ddelegate; +@property (nonatomic, readonly) float Fdelegate; +@property (nonatomic, readonly) int Idelegate; +@property (nonatomic, readonly) BOOL Bdelegate; +@end diff --git a/test/ARCMT/objcmt-property.m.result b/test/ARCMT/objcmt-property.m.result new file mode 100644 index 0000000..c6380c8 --- /dev/null +++ b/test/ARCMT/objcmt-property.m.result @@ -0,0 +1,210 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fblocks -objcmt-migrate-readwrite-property -objcmt-migrate-readonly-property -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 +// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result +// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result + +#define WEBKIT_OBJC_METHOD_ANNOTATION(ANNOTATION) ANNOTATION +#define WEAK_IMPORT_ATTRIBUTE __attribute__((objc_arc_weak_reference_unavailable)) +#define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER +#define DEPRECATED __attribute__((deprecated)) + +typedef char BOOL; +@class NSString; +@protocol NSCopying @end + +@interface NSObject <NSCopying> +@end + +@interface NSDictionary : NSObject +@end + +@interface I : NSObject { + int ivarVal; +} +@property (nonatomic, weak) NSString *WeakProp; + +@property (nonatomic, retain) NSString *StrongProp; + +@property (nonatomic, retain) NSString *UnavailProp __attribute__((unavailable)); +- (void) setUnavailProp : (NSString *)Val; + +@property (nonatomic, retain) NSString *UnavailProp1 __attribute__((unavailable)); + +@property (nonatomic, retain) NSString *UnavailProp2; +- (void) setUnavailProp2 : (NSString *)Val __attribute__((unavailable)); + +@property (nonatomic, copy) NSDictionary *undoAction; +@end + +@implementation I +@end + +@class NSArray; + +@interface MyClass2 { +@private + NSArray *_names1; + NSArray *_names2; + NSArray *_names3; + NSArray *_names4; +} +@property (nonatomic, retain) NSArray *names2; +@property (nonatomic, retain) NSArray *names3; +@property (nonatomic, retain) NSArray *names4; +@property (nonatomic, retain) NSArray *names1; +@end + +// Properties that contain the name "delegate" or "dataSource", +// or have exact name "target" have unsafe_unretained attribute. +@interface NSInvocation +@property (nonatomic, assign) id target; + +@property (nonatomic, assign) id dataSource; + +@property (nonatomic, assign) id xxxdelegateYYY; + + +@property (nonatomic, retain) id MYtarget; + +@property (nonatomic, retain) id targetX; + +@property (nonatomic) int value; + +@property (nonatomic, getter=isContinuous) BOOL continuous; + +- (id) isAnObject; +- (void)setAnObject : (id) object; + +@property (nonatomic, getter=isinValid, readonly) BOOL inValid; +- (void) setInValid : (BOOL) arg; + +- (void) Nothing; +@property (nonatomic, readonly) int Length; +@property (nonatomic, readonly, retain) id object; ++ (double) D; +@property (nonatomic, readonly) void *JSObject WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER); +@property (nonatomic, getter=isIgnoringInteractionEvents, readonly) BOOL ignoringInteractionEvents; + +@property (nonatomic, getter=getStringValue, retain) NSString *stringValue; +@property (nonatomic, getter=getCounterValue, readonly) BOOL counterValue; +@property (nonatomic, getter=getns_dixtionary, readonly, retain) NSDictionary *ns_dixtionary; + +- (BOOL)is3bar; // watch out +- (NSString *)get3foo; // watch out + +@property (nonatomic, getter=getM, readonly) BOOL m; +@property (nonatomic, getter=getMA, readonly) BOOL MA; +@property (nonatomic, getter=getALL, readonly) BOOL ALL; +@property (nonatomic, getter=getMANY, readonly) BOOL MANY; +@property (nonatomic, getter=getSome, readonly) BOOL some; +@end + + +@interface NSInvocation(CAT) +@property (nonatomic, assign) id target; + +@property (nonatomic, assign) id dataSource; + +@property (nonatomic, assign) id xxxdelegateYYY; + + +@property (nonatomic, retain) id MYtarget; + +@property (nonatomic, retain) id targetX; + +@property (nonatomic) int value; + +@property (nonatomic, getter=isContinuous) BOOL continuous; + +- (id) isAnObject; +- (void)setAnObject : (id) object; + +@property (nonatomic, getter=isinValid, readonly) BOOL inValid; +- (void) setInValid : (BOOL) arg; + +- (void) Nothing; +@property (nonatomic, readonly) int Length; +@property (nonatomic, readonly, retain) id object; ++ (double) D; + +- (BOOL)is3bar; // watch out +- (NSString *)get3foo; // watch out + +@property (nonatomic, getter=getM, readonly) BOOL m; +@property (nonatomic, getter=getMA, readonly) BOOL MA; +@property (nonatomic, getter=getALL, readonly) BOOL ALL; +@property (nonatomic, getter=getMANY, readonly) BOOL MANY; +@property (nonatomic, getter=getSome, readonly) BOOL some; +@end + +DEPRECATED +@interface I_DEP +- (BOOL) isinValid; +- (void) setInValid : (BOOL) arg; +@end + +@interface AnotherOne +- (BOOL) isinValid DEPRECATED; +- (void) setInValid : (BOOL) arg; +- (id)MYtarget; +- (void)setMYtarget: (id)target DEPRECATED; +- (BOOL) getM DEPRECATED; + +- (id)xxxdelegateYYY DEPRECATED; +- (void)setXxxdelegateYYY:(id)delegate DEPRECATED; +@end + +// rdar://14987909 +#define NS_AVAILABLE __attribute__((availability(macosx,introduced=10.0))) +#define NORETURN __attribute__((noreturn)) +#define ALIGNED __attribute__((aligned(16))) + +@interface NSURL +// Do not infer a property. +@property (nonatomic, retain) NSURL *appStoreReceiptURL NS_AVAILABLE; +- (void) setAppStoreReceiptURL : (NSURL *)object; + +@property (nonatomic, retain) NSURL *appStoreReceiptURLX NS_AVAILABLE; + +// Do not infer a property. +@property (nonatomic, retain) NSURL *appStoreReceiptURLY ; +- (void) setAppStoreReceiptURLY : (NSURL *)object NS_AVAILABLE; + +@property (nonatomic, readonly, retain) id OkToInfer NS_AVAILABLE; + +// Do not infer a property. +@property (nonatomic, retain) NSURL *appStoreReceiptURLZ ; +- (void) setAppStoreReceiptURLZ : (NSURL *)object NS_AVAILABLE; + +// Do not infer a property. +- (id) t1 NORETURN NS_AVAILABLE; +- (void) setT1 : (id) arg NS_AVAILABLE; + +@property (nonatomic, retain) id method1 ALIGNED NS_AVAILABLE; + +- (NSURL *)init; // No Change ++ (id)alloc; // No Change + +- (BOOL)is1stClass; // Not a valid property +@property (nonatomic, getter=isClass, readonly) BOOL class; // This is a valid property 'class' is not a keyword in ObjC +- (BOOL)isDouble; // Not a valid property + +@end + +// rdar://15082818 +@class NSMutableDictionary; + +@interface NSArray +@property (nonatomic, readonly, copy) id (^expressionBlock)(id, NSArray *, NSMutableDictionary *); +@property (nonatomic, copy) id (^MyBlock)(id, NSArray *, NSMutableDictionary *); +@property (nonatomic, readonly) id (*expressionFuncptr)(id, NSArray *, NSMutableDictionary *); +@property (nonatomic) id (*MyFuncptr)(id, NSArray *, NSMutableDictionary *); +@end + +// rdar://15231241 +@interface rdar15231241 +@property (nonatomic, readonly) double Ddelegate; +@property (nonatomic, readonly) float Fdelegate; +@property (nonatomic, readonly) int Idelegate; +@property (nonatomic, readonly) BOOL Bdelegate; +@end diff --git a/test/ARCMT/objcmt-protocol-conformance.m b/test/ARCMT/objcmt-protocol-conformance.m new file mode 100644 index 0000000..7bc7d93 --- /dev/null +++ b/test/ARCMT/objcmt-protocol-conformance.m @@ -0,0 +1,114 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -objcmt-migrate-protocol-conformance -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 +// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result + +@interface NSObject @end + +@protocol P +- (id) Meth1: (double) arg; +@end + +@interface Test1 // Test for no super class and no protocol list +@end + +@implementation Test1 +- (id) Meth1: (double) arg { return 0; } +@end + +@protocol P1 @end +@protocol P2 @end + +@interface Test2 <P1, P2> // Test for no super class and with protocol list +{ + id IVAR1; + id IVAR2; +} +@end + +@implementation Test2 +- (id) Meth1: (double) arg { return 0; } +@end + +@interface Test3 : NSObject { // Test for Super class and no protocol list + id IV1; +} +@end + +@implementation Test3 +- (id) Meth1: (double) arg { return 0; } +@end + +@interface Test4 : NSObject <P1, P2> // Test for Super class and protocol list +@end + +@implementation Test4 +- (id) Meth1: (double) arg { return 0; } +@end + +// Test5 - conforms to P3 because it implement's P3's property. +@protocol P3 +@property (copy) id Prop; +@end + +@protocol P4 +@property (copy) id Prop; +@end + +@interface Test5 : NSObject<P3> +@end + +@implementation Test5 +@synthesize Prop=_XXX; +@end + +@protocol P5 <P3, P4> +@property (copy) id Prop; +@end + +@protocol P6 <P3, P4, P5> +@property (copy) id Prop; +@end + +@interface Test6 : NSObject // Test for minimal listing of conforming protocols +@property (copy) id Prop; +@end + +@implementation Test6 +@end + +@class UIDynamicAnimator, UIWindow; +@interface UIResponder : NSObject +@end + +@protocol EmptyProtocol +@end + +@protocol OptionalMethodsOnly +@optional +- (void)dynamicAnimatorWillResume:(UIDynamicAnimator*)animator; +- (void)dynamicAnimatorDidPause:(UIDynamicAnimator*)animator; +@end + +@protocol OptionalPropertiesOnly +@optional +@property (strong, nonatomic) id OptionalProperty; +@end + +@protocol OptionalEvrything +@optional +- (void)dynamicAnimatorWillResume:(UIDynamicAnimator*)animator; +@property (strong, nonatomic) id OptionalProperty; +- (void)dynamicAnimatorDidPause:(UIDynamicAnimator*)animator; +@end + +@protocol UIApplicationDelegate +@end + +@interface Test7 : UIResponder <UIApplicationDelegate> +@property (strong, nonatomic) UIWindow *window; +@end + +@implementation Test7 +@end + diff --git a/test/ARCMT/objcmt-protocol-conformance.m.result b/test/ARCMT/objcmt-protocol-conformance.m.result new file mode 100644 index 0000000..dc0874c --- /dev/null +++ b/test/ARCMT/objcmt-protocol-conformance.m.result @@ -0,0 +1,114 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -objcmt-migrate-protocol-conformance -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 +// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result + +@interface NSObject @end + +@protocol P +- (id) Meth1: (double) arg; +@end + +@interface Test1<P> // Test for no super class and no protocol list +@end + +@implementation Test1 +- (id) Meth1: (double) arg { return 0; } +@end + +@protocol P1 @end +@protocol P2 @end + +@interface Test2 <P1, P2, P> // Test for no super class and with protocol list +{ + id IVAR1; + id IVAR2; +} +@end + +@implementation Test2 +- (id) Meth1: (double) arg { return 0; } +@end + +@interface Test3 : NSObject<P> { // Test for Super class and no protocol list + id IV1; +} +@end + +@implementation Test3 +- (id) Meth1: (double) arg { return 0; } +@end + +@interface Test4 : NSObject <P1, P2, P> // Test for Super class and protocol list +@end + +@implementation Test4 +- (id) Meth1: (double) arg { return 0; } +@end + +// Test5 - conforms to P3 because it implement's P3's property. +@protocol P3 +@property (copy) id Prop; +@end + +@protocol P4 +@property (copy) id Prop; +@end + +@interface Test5 : NSObject<P3, P4> +@end + +@implementation Test5 +@synthesize Prop=_XXX; +@end + +@protocol P5 <P3, P4> +@property (copy) id Prop; +@end + +@protocol P6 <P3, P4, P5> +@property (copy) id Prop; +@end + +@interface Test6 : NSObject<P6> // Test for minimal listing of conforming protocols +@property (copy) id Prop; +@end + +@implementation Test6 +@end + +@class UIDynamicAnimator, UIWindow; +@interface UIResponder : NSObject +@end + +@protocol EmptyProtocol +@end + +@protocol OptionalMethodsOnly +@optional +- (void)dynamicAnimatorWillResume:(UIDynamicAnimator*)animator; +- (void)dynamicAnimatorDidPause:(UIDynamicAnimator*)animator; +@end + +@protocol OptionalPropertiesOnly +@optional +@property (strong, nonatomic) id OptionalProperty; +@end + +@protocol OptionalEvrything +@optional +- (void)dynamicAnimatorWillResume:(UIDynamicAnimator*)animator; +@property (strong, nonatomic) id OptionalProperty; +- (void)dynamicAnimatorDidPause:(UIDynamicAnimator*)animator; +@end + +@protocol UIApplicationDelegate +@end + +@interface Test7 : UIResponder <UIApplicationDelegate> +@property (strong, nonatomic) UIWindow *window; +@end + +@implementation Test7 +@end + diff --git a/test/ARCMT/verify.m b/test/ARCMT/verify.m index bfb3b4b..02f7fcc 100644 --- a/test/ARCMT/verify.m +++ b/test/ARCMT/verify.m @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -arcmt-check -verify %s -// RUN: %clang_cc1 -arcmt-check -verify %t.invalid 2>&1 | FileCheck %s +// RUN: not %clang_cc1 -arcmt-check -verify %t.invalid 2>&1 | FileCheck %s #if 0 // expected-error {{should be ignored}} diff --git a/test/ARCMT/whitelisted/Inputs/header1.h b/test/ARCMT/whitelisted/Inputs/header1.h new file mode 100644 index 0000000..44430f3 --- /dev/null +++ b/test/ARCMT/whitelisted/Inputs/header1.h @@ -0,0 +1 @@ +// the contents are not important diff --git a/test/ARCMT/whitelisted/header1.h b/test/ARCMT/whitelisted/header1.h new file mode 100644 index 0000000..a3014eb --- /dev/null +++ b/test/ARCMT/whitelisted/header1.h @@ -0,0 +1,5 @@ + +@interface I1 : NSObject +-(int)prop; +-(void)setProp:(int)p; +@end diff --git a/test/ARCMT/whitelisted/header1.h.result b/test/ARCMT/whitelisted/header1.h.result new file mode 100644 index 0000000..7808fc8 --- /dev/null +++ b/test/ARCMT/whitelisted/header1.h.result @@ -0,0 +1,4 @@ + +@interface I1 : NSObject +@property (nonatomic) int prop; +@end diff --git a/test/ARCMT/whitelisted/header2.h b/test/ARCMT/whitelisted/header2.h new file mode 100644 index 0000000..c7577ed --- /dev/null +++ b/test/ARCMT/whitelisted/header2.h @@ -0,0 +1,5 @@ + +@interface I2 : NSObject +-(int)prop; +-(void)setProp:(int)p; +@end diff --git a/test/ARCMT/whitelisted/header2.h.result b/test/ARCMT/whitelisted/header2.h.result new file mode 100644 index 0000000..b1b5270 --- /dev/null +++ b/test/ARCMT/whitelisted/header2.h.result @@ -0,0 +1,4 @@ + +@interface I2 : NSObject +@property (nonatomic) int prop; +@end diff --git a/test/ARCMT/whitelisted/objcmt-with-whitelist.m b/test/ARCMT/whitelisted/objcmt-with-whitelist.m new file mode 100644 index 0000000..1b44c9a --- /dev/null +++ b/test/ARCMT/whitelisted/objcmt-with-whitelist.m @@ -0,0 +1,12 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -objcmt-migrate-readwrite-property %s -triple x86_64-apple-darwin11 -migrate -o %t.remap +// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %S/header1.h.result %S/header2.h.result +// RUN: %clang_cc1 -objcmt-migrate-readwrite-property -objcmt-white-list-dir-path=%S/Inputs %s -triple x86_64-apple-darwin11 -migrate -o %t.remap +// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %S/header1.h.result + +@interface NSObject ++ (id)alloc; +@end + +#include "header1.h" +#include "header2.h" diff --git a/test/ARCMT/with-arc-mode-check.m b/test/ARCMT/with-arc-mode-check.m deleted file mode 100644 index 33f31f5..0000000 --- a/test/ARCMT/with-arc-mode-check.m +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: %clang_cc1 -arcmt-check -fsyntax-only -fobjc-arc -x objective-c %s - -@protocol NSObject -- (oneway void)release; -@end - -void test1(id p) { - [p release]; -} diff --git a/test/ARCMT/with-arc-mode-migrate.m b/test/ARCMT/with-arc-mode-migrate.m deleted file mode 100644 index 4688594..0000000 --- a/test/ARCMT/with-arc-mode-migrate.m +++ /dev/null @@ -1,13 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: %clang_cc1 -arcmt-migrate -mt-migrate-directory %t -fsyntax-only -fobjc-arc %s -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: rm -rf %t - -@protocol NSObject -- (oneway void)release; -@end - -void test1(id p) { - [p release]; -} diff --git a/test/ARCMT/with-arc-mode-migrate.m.result b/test/ARCMT/with-arc-mode-migrate.m.result deleted file mode 100644 index dd34b99..0000000 --- a/test/ARCMT/with-arc-mode-migrate.m.result +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: %clang_cc1 -arcmt-migrate -mt-migrate-directory %t -fsyntax-only -fobjc-arc %s -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: rm -rf %t - -@protocol NSObject -- (oneway void)release; -@end - -void test1(id p) { -} |