diff options
author | John McCall <rjmccall@apple.com> | 2011-06-15 23:25:17 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2011-06-15 23:25:17 +0000 |
commit | 8f0e8d22960d56f8390f4971e2c0f2f0a0884602 (patch) | |
tree | 288fc5496bfa36bab70b98f3be6bb5cd13645214 /test | |
parent | f85e193739c953358c865005855253af4f68a497 (diff) | |
download | clang-8f0e8d22960d56f8390f4971e2c0f2f0a0884602.tar.gz |
The ARC Migration Tool. All the credit goes to Argyrios and Fariborz
for this.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133104 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test')
42 files changed, 2003 insertions, 0 deletions
diff --git a/test/ARCMT/Common.h b/test/ARCMT/Common.h new file mode 100644 index 0000000000..1ddfef942d --- /dev/null +++ b/test/ARCMT/Common.h @@ -0,0 +1,72 @@ +#if __has_feature(objc_arr) +#define NS_AUTOMATED_REFCOUNT_UNAVAILABLE __attribute__((unavailable("not available in automatic reference counting mode"))) +#else +#define NS_AUTOMATED_REFCOUNT_UNAVAILABLE +#endif + +typedef struct _NSZone NSZone; +typedef int BOOL; +typedef unsigned NSUInteger; +typedef int int32_t; +typedef unsigned char uint8_t; +typedef int32_t UChar32; +typedef unsigned char UChar; + +@protocol NSObject +- (BOOL)isEqual:(id)object; +- (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; + +- (NSZone *)zone NS_AUTOMATED_REFCOUNT_UNAVAILABLE; +@end + +@protocol NSCopying +- (id)copyWithZone:(NSZone *)zone; +@end + +@protocol NSMutableCopying +- (id)mutableCopyWithZone:(NSZone *)zone; +@end + +@interface NSObject <NSObject> {} +- (id)init; + ++ (id)new; ++ (id)allocWithZone:(NSZone *)zone NS_AUTOMATED_REFCOUNT_UNAVAILABLE; ++ (id)alloc; +- (void)dealloc; + +- (void)finalize; + +- (id)copy; +- (id)mutableCopy; + ++ (id)copyWithZone:(NSZone *)zone NS_AUTOMATED_REFCOUNT_UNAVAILABLE; ++ (id)mutableCopyWithZone:(NSZone *)zone NS_AUTOMATED_REFCOUNT_UNAVAILABLE; +@end + +extern void NSRecycleZone(NSZone *zone); + +NS_AUTOMATED_REFCOUNT_UNAVAILABLE +@interface NSAutoreleasePool : NSObject { +@private + void *_token; + void *_reserved3; + void *_reserved2; + void *_reserved; +} + ++ (void)addObject:(id)anObject; + +- (void)addObject:(id)anObject; + +- (void)drain; + +@end + +typedef const void* objc_objectptr_t; +extern __attribute__((ns_returns_retained)) id objc_retainedObject(objc_objectptr_t __attribute__((cf_consumed)) pointer); +extern __attribute__((ns_returns_not_retained)) id objc_unretainedObject(objc_objectptr_t pointer); +extern objc_objectptr_t objc_unretainedPointer(id object); diff --git a/test/ARCMT/alloc-with-zone-check.m b/test/ARCMT/alloc-with-zone-check.m new file mode 100644 index 0000000000..a987fa8b84 --- /dev/null +++ b/test/ARCMT/alloc-with-zone-check.m @@ -0,0 +1,80 @@ +// RUN: arcmt-test -check-only -verify --args %s + +#if __has_feature(objc_arr) +#define NS_AUTOMATED_REFCOUNT_UNAVAILABLE __attribute__((unavailable("not available in automatic reference counting mode"))) +#else +#define NS_AUTOMATED_REFCOUNT_UNAVAILABLE +#endif + +typedef struct _NSZone NSZone; +typedef int BOOL; +typedef unsigned NSUInteger; + +@protocol NSObject +- (BOOL)isEqual:(id)object; +- (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; + +- (NSZone *)zone NS_AUTOMATED_REFCOUNT_UNAVAILABLE; // expected-note {{marked unavailable here}} +@end + +@protocol NSCopying +- (id)copyWithZone:(NSZone *)zone; +@end + +@protocol NSMutableCopying +- (id)mutableCopyWithZone:(NSZone *)zone; +@end + +@interface NSObject <NSObject> {} +- (id)init; + ++ (id)allocWithZone:(NSZone *)zone NS_AUTOMATED_REFCOUNT_UNAVAILABLE; // expected-note 2 {{marked unavailable here}} ++ (id)alloc; +- (void)dealloc; + +- (void)finalize; + +- (id)copy; +- (id)mutableCopy; + ++ (id)copyWithZone:(NSZone *)zone NS_AUTOMATED_REFCOUNT_UNAVAILABLE; ++ (id)mutableCopyWithZone:(NSZone *)zone NS_AUTOMATED_REFCOUNT_UNAVAILABLE; +@end + +extern void NSRecycleZone(NSZone *zone); + +id IhaveSideEffect(); + +@interface Foo : NSObject <NSCopying, NSMutableCopying> { + id bar; +} +@property (retain) id bar; +-(id)test:(id)obj; +@end + +@implementation Foo + +@synthesize bar; + +-(id)test:(id)obj { + Foo *foo1 = [[Foo allocWithZone:[self zone]] init]; + Foo *foo2 = [[Foo allocWithZone:[super zone]] init]; + Foo *foo3 = [[Foo allocWithZone:[IhaveSideEffect() zone]] init]; // expected-error {{not available}} + NSRecycleZone([self zone]); // expected-error {{not available}} + + foo1 = [foo1 copyWithZone:[self zone]]; + foo2 = [foo1 copyWithZone:[super zone]]; + foo3 = [foo1 copyWithZone:[IhaveSideEffect() zone]]; + foo1 = [foo1 mutableCopyWithZone:[self zone]]; + + return foo1; +} + ++(id)allocWithZone:(NSZone *)zone { + return [super allocWithZone:zone]; // expected-error {{not available in automatic reference counting mode}} +} + +@end diff --git a/test/ARCMT/alloc-with-zone.m b/test/ARCMT/alloc-with-zone.m new file mode 100644 index 0000000000..b8b78d1ed4 --- /dev/null +++ b/test/ARCMT/alloc-with-zone.m @@ -0,0 +1,42 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -arch x86_64 %s > %t +// RUN: diff %t %s.result + +#include "Common.h" + +@interface Foo : NSObject <NSCopying, NSMutableCopying> { + id bar; +} +@property (retain) id bar; +-(id)test:(NSZone *)z; +@end + +@implementation Foo + +@synthesize bar; + ++(id)class_test:(NSZone *)z { + return [self allocWithZone:z]; +} + +-(id)test:(NSZone *)z { + NSZone *z2 = [self zone], *z3 = z2; + NSZone *z4 = z3; + + Foo *foo1 = [[Foo allocWithZone:[self zone]] init]; + Foo *foo2 = [[Foo allocWithZone:[super zone]] init]; + Foo *foo3 = [[Foo allocWithZone:z] init]; + + Foo *foo4 = [[Foo allocWithZone:z2] init]; + Foo *foo5 = [[Foo allocWithZone:z3] init]; + Foo *foo6 = [[Foo allocWithZone:z4] init]; + + foo1 = [foo1 copyWithZone:[self zone]]; + foo2 = [foo1 copyWithZone:[super zone]]; + foo3 = [foo1 copyWithZone:z]; + foo1 = [foo1 mutableCopyWithZone:[self zone]]; + + return foo1; +} + +@end diff --git a/test/ARCMT/alloc-with-zone.m.result b/test/ARCMT/alloc-with-zone.m.result new file mode 100644 index 0000000000..52daed619e --- /dev/null +++ b/test/ARCMT/alloc-with-zone.m.result @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -arch x86_64 %s > %t +// RUN: diff %t %s.result + +#include "Common.h" + +@interface Foo : NSObject <NSCopying, NSMutableCopying> { + id bar; +} +@property (retain) id bar; +-(id)test:(NSZone *)z; +@end + +@implementation Foo + +@synthesize bar; + ++(id)class_test:(NSZone *)z { + return [self alloc]; +} + +-(id)test:(NSZone *)z { + + Foo *foo1 = [[Foo alloc] init]; + Foo *foo2 = [[Foo alloc] init]; + Foo *foo3 = [[Foo alloc] init]; + + Foo *foo4 = [[Foo alloc] init]; + Foo *foo5 = [[Foo alloc] init]; + Foo *foo6 = [[Foo alloc] init]; + + foo1 = [foo1 copy]; + foo2 = [foo1 copy]; + foo3 = [foo1 copy]; + foo1 = [foo1 mutableCopy]; + + return foo1; +} + +@end diff --git a/test/ARCMT/assign-prop-no-arc-runtime.m b/test/ARCMT/assign-prop-no-arc-runtime.m new file mode 100644 index 0000000000..07a5b40b6f --- /dev/null +++ b/test/ARCMT/assign-prop-no-arc-runtime.m @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -fobjc-no-arc-runtime -x objective-c %s.result +// RUN: arcmt-test --args -arch x86_64 %s -D__IPHONE_OS_VERSION_MIN_REQUIRED=40300 > %t +// RUN: diff %t %s.result +// RUN: arcmt-test --args -arch x86_64 %s -miphoneos-version-min=4.3 > %t +// RUN: diff %t %s.result +// RUN: arcmt-test --args -arch x86_64 %s -mmacosx-version-min=10.6 > %t +// RUN: diff %t %s.result + +#include "Common.h" + +@interface Foo : NSObject { + NSObject *x; +} +@property (readonly,assign) id x; +@end + +@implementation Foo +@synthesize x; +@end diff --git a/test/ARCMT/assign-prop-no-arc-runtime.m.result b/test/ARCMT/assign-prop-no-arc-runtime.m.result new file mode 100644 index 0000000000..69909f3416 --- /dev/null +++ b/test/ARCMT/assign-prop-no-arc-runtime.m.result @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -fobjc-no-arc-runtime -x objective-c %s.result +// RUN: arcmt-test --args -arch x86_64 %s -D__IPHONE_OS_VERSION_MIN_REQUIRED=40300 > %t +// RUN: diff %t %s.result +// RUN: arcmt-test --args -arch x86_64 %s -miphoneos-version-min=4.3 > %t +// RUN: diff %t %s.result +// RUN: arcmt-test --args -arch x86_64 %s -mmacosx-version-min=10.6 > %t +// RUN: diff %t %s.result + +#include "Common.h" + +@interface Foo : NSObject { + NSObject *__unsafe_unretained x; +} +@property (readonly,assign) id x; +@end + +@implementation Foo +@synthesize x; +@end diff --git a/test/ARCMT/assign-prop-with-arc-runtime.m b/test/ARCMT/assign-prop-with-arc-runtime.m new file mode 100644 index 0000000000..86f5fbb616 --- /dev/null +++ b/test/ARCMT/assign-prop-with-arc-runtime.m @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -arch x86_64 %s -D__IPHONE_OS_VERSION_MIN_REQUIRED=50000 > %t +// RUN: diff %t %s.result +// RUN: arcmt-test --args -arch x86_64 %s -miphoneos-version-min=5.0 > %t +// RUN: diff %t %s.result +// RUN: arcmt-test --args -arch x86_64 %s -mmacosx-version-min=10.7 > %t +// RUN: diff %t %s.result + +#include "Common.h" + +@interface Foo : NSObject { + NSObject *x, *w, *q1, *q2; + NSObject *z1, *__unsafe_unretained z2; +} +@property (readonly,assign) id x; +@property (assign) id w; +@property (assign) id q1, q2; +@property (assign) id z1, z2; +@end + +@implementation Foo +@synthesize x,w,q1,q2,z1,z2; +@end diff --git a/test/ARCMT/assign-prop-with-arc-runtime.m.result b/test/ARCMT/assign-prop-with-arc-runtime.m.result new file mode 100644 index 0000000000..59f7608278 --- /dev/null +++ b/test/ARCMT/assign-prop-with-arc-runtime.m.result @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -arch x86_64 %s -D__IPHONE_OS_VERSION_MIN_REQUIRED=50000 > %t +// RUN: diff %t %s.result +// RUN: arcmt-test --args -arch x86_64 %s -miphoneos-version-min=5.0 > %t +// RUN: diff %t %s.result +// RUN: arcmt-test --args -arch x86_64 %s -mmacosx-version-min=10.7 > %t +// RUN: diff %t %s.result + +#include "Common.h" + +@interface Foo : NSObject { + NSObject *__weak x, *__weak w, *__weak q1, *__weak q2; + NSObject *__unsafe_unretained z1, *__unsafe_unretained z2; +} +@property (readonly,weak) id x; +@property (weak) id w; +@property (weak) id q1, q2; +@property (assign) id z1, z2; +@end + +@implementation Foo +@synthesize x,w,q1,q2,z1,z2; +@end diff --git a/test/ARCMT/atautorelease-2.m b/test/ARCMT/atautorelease-2.m new file mode 100644 index 0000000000..919e10edf2 --- /dev/null +++ b/test/ARCMT/atautorelease-2.m @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -arch x86_64 %s > %t +// RUN: diff %t %s.result + +@interface NSAutoreleasePool +- drain; ++new; ++alloc; +-init; +-autorelease; +-release; +@end + +void NSLog(id, ...); + +int main (int argc, const char * argv[]) { + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + NSAutoreleasePool *chunkPool = [[NSAutoreleasePool alloc] init]; + + while (argc) { + [chunkPool release]; + return 0; + } + + [chunkPool drain]; + [pool drain]; + + return 0; +} diff --git a/test/ARCMT/atautorelease-2.m.result b/test/ARCMT/atautorelease-2.m.result new file mode 100644 index 0000000000..7a55cb43ae --- /dev/null +++ b/test/ARCMT/atautorelease-2.m.result @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -arch x86_64 %s > %t +// RUN: diff %t %s.result + +@interface NSAutoreleasePool +- drain; ++new; ++alloc; +-init; +-autorelease; +-release; +@end + +void NSLog(id, ...); + +int main (int argc, const char * argv[]) { + @autoreleasepool { + @autoreleasepool { + + while (argc) { + return 0; + } + + } + } + + return 0; +} diff --git a/test/ARCMT/atautorelease-3.m b/test/ARCMT/atautorelease-3.m new file mode 100644 index 0000000000..4498908472 --- /dev/null +++ b/test/ARCMT/atautorelease-3.m @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -arch x86_64 %s > %t +// RUN: diff %t %s.result + +@interface NSAutoreleasePool +- drain; ++new; ++alloc; +-init; +-autorelease; +- release; +@end + +void NSLog(id, ...); + +void test1(int x) { + // All this stuff get removed since nothing is happening inside. + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + NSAutoreleasePool *chunkPool = [[NSAutoreleasePool alloc] init]; + while (x) { + chunkPool = [[NSAutoreleasePool alloc] init]; + [chunkPool release]; + } + + [chunkPool drain]; + [pool drain]; +} + +void test2(int x) { + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + NSAutoreleasePool *chunkPool = [[NSAutoreleasePool alloc] init]; + while (x) { + chunkPool = [[NSAutoreleasePool alloc] init]; + ++x; + [chunkPool release]; + } + + [chunkPool drain]; + [pool drain]; +} diff --git a/test/ARCMT/atautorelease-3.m.result b/test/ARCMT/atautorelease-3.m.result new file mode 100644 index 0000000000..51b0e570b6 --- /dev/null +++ b/test/ARCMT/atautorelease-3.m.result @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -arch x86_64 %s > %t +// RUN: diff %t %s.result + +@interface NSAutoreleasePool +- drain; ++new; ++alloc; +-init; +-autorelease; +- release; +@end + +void NSLog(id, ...); + +void test1(int x) { + // All this stuff get removed since nothing is happening inside. +} + +void test2(int x) { + @autoreleasepool { + @autoreleasepool { + while (x) { + @autoreleasepool { + ++x; + } + } + + } + } +} diff --git a/test/ARCMT/atautorelease-check.m b/test/ARCMT/atautorelease-check.m new file mode 100644 index 0000000000..126642cd38 --- /dev/null +++ b/test/ARCMT/atautorelease-check.m @@ -0,0 +1,144 @@ +// RUN: arcmt-test -check-only -verify --args %s + +#if __has_feature(objc_arr) +#define NS_AUTOMATED_REFCOUNT_UNAVAILABLE __attribute__((unavailable("not available in automatic reference counting mode"))) +#else +#define NS_AUTOMATED_REFCOUNT_UNAVAILABLE +#endif + +typedef struct _NSZone NSZone; +typedef int BOOL; +typedef unsigned NSUInteger; + +@protocol NSObject +- (BOOL)isEqual:(id)object; +- (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; + +- (NSZone *)zone NS_AUTOMATED_REFCOUNT_UNAVAILABLE; +@end + +@protocol NSCopying +- (id)copyWithZone:(NSZone *)zone; +@end + +@protocol NSMutableCopying +- (id)mutableCopyWithZone:(NSZone *)zone; +@end + +@interface NSObject <NSObject> {} +- (id)init; + ++ (id)new; ++ (id)allocWithZone:(NSZone *)zone NS_AUTOMATED_REFCOUNT_UNAVAILABLE; ++ (id)alloc; +- (void)dealloc; + +- (void)finalize; + +- (id)copy; +- (id)mutableCopy; + ++ (id)copyWithZone:(NSZone *)zone NS_AUTOMATED_REFCOUNT_UNAVAILABLE; ++ (id)mutableCopyWithZone:(NSZone *)zone NS_AUTOMATED_REFCOUNT_UNAVAILABLE; +@end + +extern void NSRecycleZone(NSZone *zone); + +NS_AUTOMATED_REFCOUNT_UNAVAILABLE +@interface NSAutoreleasePool : NSObject { // expected-note 13 {{marked unavailable here}} +@private + void *_token; + void *_reserved3; + void *_reserved2; + void *_reserved; +} + ++ (void)addObject:(id)anObject; + +- (void)addObject:(id)anObject; + +- (void)drain; + +@end + + +void NSLog(id, ...); + +int main (int argc, const char * argv[]) { + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + NSAutoreleasePool *chunkPool = [[NSAutoreleasePool alloc] init]; // expected-error 2 {{'NSAutoreleasePool' is unavailable}} + + while (argc) { + [chunkPool release]; + // the following pool was not released in this scope, don't touch it. + chunkPool = [[NSAutoreleasePool alloc] init]; // expected-error {{'NSAutoreleasePool' is unavailable}} + } + + [chunkPool drain]; + [pool drain]; + + return 0; +} + +void f(void) { + NSAutoreleasePool * pool; // expected-error {{'NSAutoreleasePool' is unavailable}} + + for (int i=0; i != 10; ++i) { + id x = pool; // We won't touch a NSAutoreleasePool if we can't safely + // remove all the references to it. + } + + pool = [[NSAutoreleasePool alloc] init]; // expected-error {{'NSAutoreleasePool' is unavailable}} + NSLog(@"%s", "YES"); + [pool release]; +} + +void f2(void) { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // expected-error 2 {{'NSAutoreleasePool' is unavailable}} \ + // expected-note {{scope begins here}} + + // 'x' is declared inside the "pool scope" but used outside it, if we create + // a @autorelease scope it will be undefined outside it so don't touch the pool. + int x = 0; // expected-note {{declared here}} + + [pool release]; // expected-note {{scope ends here}} + + ++x; // expected-error {{a name is referenced outside the NSAutoreleasePool scope that it was declared in}} +} + +void f3(void) { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // expected-error 2 {{'NSAutoreleasePool' is unavailable}} \ + // expected-note {{scope begins here}} + + struct S { int x; }; // expected-note {{declared here}} + + [pool release]; // expected-note {{scope ends here}} + + struct S *var; // expected-error {{a name is referenced outside the NSAutoreleasePool scope that it was declared in}} + var->x = 0; +} + +void f4(void) { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // expected-error 2 {{'NSAutoreleasePool' is unavailable}} \ + // expected-note {{scope begins here}} + + enum { Bar }; // expected-note {{declared here}} + + [pool release]; // expected-note {{scope ends here}} + + int x = Bar; // expected-error {{a name is referenced outside the NSAutoreleasePool scope that it was declared in}} +} + +void f5(void) { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // expected-error 2 {{'NSAutoreleasePool' is unavailable}} \ + // expected-note {{scope begins here}} + + typedef int Bar; // expected-note {{declared here}} + + [pool release]; // expected-note {{scope ends here}} + + Bar x; // expected-error {{a name is referenced outside the NSAutoreleasePool scope that it was declared in}} +} diff --git a/test/ARCMT/atautorelease.m b/test/ARCMT/atautorelease.m new file mode 100644 index 0000000000..fa1a24b916 --- /dev/null +++ b/test/ARCMT/atautorelease.m @@ -0,0 +1,47 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -arch x86_64 %s > %t +// RUN: diff %t %s.result + +#include "Common.h" + +void NSLog(id, ...); + +int main (int argc, const char * argv[]) { + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + + if (argc) { + NSAutoreleasePool * pool = [NSAutoreleasePool new]; + NSLog(@"%s", "YES"); + [pool drain]; + } + [pool drain]; + + NSAutoreleasePool * pool1 = [[NSAutoreleasePool alloc] init]; + NSLog(@"%s", "YES"); + [pool1 release]; + + return 0; +} + +void f(void) { + NSAutoreleasePool *pool1; + + pool1 = [NSAutoreleasePool new]; + int x = 4; + + NSAutoreleasePool *pool2 = [[NSAutoreleasePool alloc] init]; + ++x; + [pool2 drain]; + + [pool1 release]; +} + +int UIApplicationMain(int argc, char *argv[]); + +int main2(int argc, char *argv[]) { + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int result = UIApplicationMain(argc, argv); + [pool release]; + return result; +} diff --git a/test/ARCMT/atautorelease.m.result b/test/ARCMT/atautorelease.m.result new file mode 100644 index 0000000000..8cd649aba9 --- /dev/null +++ b/test/ARCMT/atautorelease.m.result @@ -0,0 +1,46 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -arch x86_64 %s > %t +// RUN: diff %t %s.result + +#include "Common.h" + +void NSLog(id, ...); + +int main (int argc, const char * argv[]) { + + @autoreleasepool { + + if (argc) { + @autoreleasepool { + NSLog(@"%s", "YES"); + } + } + } + + @autoreleasepool { + NSLog(@"%s", "YES"); + } + + return 0; +} + +void f(void) { + + @autoreleasepool { + int x = 4; + + @autoreleasepool { + ++x; + } + + } +} + +int UIApplicationMain(int argc, char *argv[]); + +int main2(int argc, char *argv[]) { + @autoreleasepool { + int result = UIApplicationMain(argc, argv); + return result; + } +} diff --git a/test/ARCMT/autoreleases.m b/test/ARCMT/autoreleases.m new file mode 100644 index 0000000000..284d92773d --- /dev/null +++ b/test/ARCMT/autoreleases.m @@ -0,0 +1,48 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -arch x86_64 %s > %t +// RUN: diff %t %s.result + +typedef unsigned char BOOL; + +@interface NSObject { + id isa; +} ++new; ++alloc; +-init; +-autorelease; +@end + +@interface NSAutoreleasePool : NSObject +- drain; +@end + +@interface A : NSObject { +@package + id object; +} +@end + +@interface B : NSObject +- (BOOL)containsSelf:(A*)a; +@end + +@implementation A +@end + +@implementation B +- (BOOL)containsSelf:(A*)a { + return a->object == self; +} +@end + +void NSLog(id, ...); + +int main (int argc, const char * argv[]) { + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + A *a = [[A new] autorelease]; + B *b = [[B new] autorelease]; + NSLog(@"%s", [b containsSelf:a] ? "YES" : "NO"); + [pool drain]; + return 0; +} diff --git a/test/ARCMT/autoreleases.m.result b/test/ARCMT/autoreleases.m.result new file mode 100644 index 0000000000..fb2959fa90 --- /dev/null +++ b/test/ARCMT/autoreleases.m.result @@ -0,0 +1,48 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -arch x86_64 %s > %t +// RUN: diff %t %s.result + +typedef unsigned char BOOL; + +@interface NSObject { + id isa; +} ++new; ++alloc; +-init; +-autorelease; +@end + +@interface NSAutoreleasePool : NSObject +- drain; +@end + +@interface A : NSObject { +@package + id object; +} +@end + +@interface B : NSObject +- (BOOL)containsSelf:(A*)a; +@end + +@implementation A +@end + +@implementation B +- (BOOL)containsSelf:(A*)a { + return a->object == self; +} +@end + +void NSLog(id, ...); + +int main (int argc, const char * argv[]) { + @autoreleasepool { + A *a = [A new]; + B *b = [B new]; + NSLog(@"%s", [b containsSelf:a] ? "YES" : "NO"); + } + return 0; +} diff --git a/test/ARCMT/checking.m b/test/ARCMT/checking.m new file mode 100644 index 0000000000..ffb245e8bb --- /dev/null +++ b/test/ARCMT/checking.m @@ -0,0 +1,255 @@ +// RUN: arcmt-test -check-only -verify --args %s + +#include "Common.h" + +typedef const struct __CFString * CFStringRef; +extern const CFStringRef kUTTypePlainText; +extern const CFStringRef kUTTypeRTF; +@class NSString; +@class A; + +struct UnsafeS { + A *__unsafe_unretained unsafeObj; +}; + +@interface A : NSObject +- (id)retain; +- (id)retainCount; +- (id)autorelease; +- (id)init; +- (oneway void)release; +- (void)dealloc; +-(void)test; +@end + +@implementation A +-(void)test { + [super dealloc]; +} +-(void)dealloc { + [super dealloc]; +} + +- (id)retain { return self; } // expected-error {{ARC forbids implementation}} +- (id)retainCount { return self; } // expected-error {{ARC forbids implementation}} +- (id)autorelease { return self; } // expected-error {{ARC forbids implementation}} +- (oneway void)release { } // expected-error {{ARC forbids implementation}} +@end + +void test1(A *a, BOOL b, struct UnsafeS *unsafeS) { + [unsafeS->unsafeObj retain]; // expected-error {{It is not safe to remove 'retain' message on an __unsafe_unretained type}} \ + // expected-error {{ARC forbids explicit message send}} + [a dealloc]; + [a retain]; + [a retainCount]; // expected-error {{ARC forbids explicit message send of 'retainCount'}} + [a release]; + [a autorelease]; + + CFStringRef cfstr; + 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 __bridge_transfer to transfer ownership of a +1 'CFStringRef' (aka 'const struct __CFString *') into ARC}} + str = (NSString *)kUTTypePlainText; + str = b ? kUTTypeRTF : kUTTypePlainText; + str = (NSString *)(b ? kUTTypeRTF : kUTTypePlainText); + str = (NSString *)a; // no change. + + SEL s = @selector(retain); // expected-error {{ARC forbids use of 'retain' in a @selector}} + s = @selector(release); // expected-error {{ARC forbids use of 'release' in a @selector}} + s = @selector(autorelease); // expected-error {{ARC forbids use of 'autorelease' in a @selector}} + s = @selector(dealloc); // expected-error {{ARC forbids use of 'dealloc' in a @selector}} + + static id __autoreleasing X1; // expected-error {{global variables cannot have __autoreleasing lifetime}} +} + +struct S { + A* a; // expected-error {{ARC forbids Objective-C objects in structs or unions}} +}; + +@interface B +-(id)alloc; +- (id)initWithInt: (int) i; +@end + +void rdar8861761() { + B *o1 = [[B alloc] initWithInt:0]; + B *o2 = [B alloc]; + [o2 initWithInt:0]; +} + +@interface Test13 +- (id) init0; +- (void) noninit; +@end +@implementation Test13 +- (id) init0 { + self = 0; +} +- (void) noninit { + self = 0; // expected-error {{cannot assign to 'self' outside of a method in the init family}} + + for (id x in collection) { // expected-error {{use of undeclared identifier 'collection'}} + x = 0; + } +} +@end + +void * cvt(id arg) +{ + void* voidp_val; + (void)(int*)arg; // expected-error {{disallowed}} + (void)(id)arg; + (void)(__autoreleasing id*)arg; // expected-error {{disallowed}} + (void)(id*)arg; // expected-error {{pointer to non-const type 'id' with no explicit lifetime}} expected-error {{disallowed}} + + (void)(__autoreleasing id**)voidp_val; + (void)(void*)voidp_val; + (void)(void**)arg; // expected-error {{disallowed}} + cvt((void*)arg); // expected-error {{requires a bridged cast}} expected-error {{disallowed}} \ + // expected-note {{use __bridge}} expected-note {{use __bridge_retained}} + cvt(0); + (void)(__strong id**)(0); + return arg; // expected-error {{disallowed}} +} + + +void test12(id collection) { + for (id x in collection) { + x = 0; + } + + for (__strong id x in collection) { + x = 0; + } +} + +void test6(unsigned cond) { + // FIXME: Fix this automatically ? + switch (cond) { + case 0: + ; + id x; // expected-note {{jump bypasses initialization of retaining variable}} + + case 1: // expected-error {{switch case is in protected scope}} + break; + } +} + +@class Test8_incomplete; +@interface Test8_complete @end; +@interface Test8_super @end; +@interface Test8 : Test8_super +- (id) init00; +- (id) init01; // expected-note {{declaration in interface}} +- (id) init02; +- (id) init03; // covariance +- (id) init04; // covariance +- (id) init05; + +- (void) init10; // expected-note {{declaration in interface is not in the 'init' family because its result type is not an object pointer}} +- (void) init11; +- (void) init12; +- (void) init13; // expected-note {{declaration in interface is not in the 'init' family because its result type is not an object pointer}} +- (void) init14; // expected-note {{declaration in interface is not in the 'init' family because its result type is not an object pointer}} +- (void) init15; + +// These should be invalid to actually call. +- (Test8_incomplete*) init20; +- (Test8_incomplete*) init21; // expected-note {{declaration in interface}} +- (Test8_incomplete*) init22; +- (Test8_incomplete*) init23; +- (Test8_incomplete*) init24; +- (Test8_incomplete*) init25; + +- (Test8_super*) init30; // id exception to covariance +- (Test8_super*) init31; // expected-note {{declaration in interface}} +- (Test8_super*) init32; +- (Test8_super*) init33; +- (Test8_super*) init34; // covariance +- (Test8_super*) init35; + +- (Test8*) init40; // id exception to covariance +- (Test8*) init41; // expected-note {{declaration in interface}} +- (Test8*) init42; +- (Test8*) init43; // this should be a warning, but that's a general language thing, not an ARC thing +- (Test8*) init44; +- (Test8*) init45; + +- (Test8_complete*) init50; // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_complete*) init51; // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_complete*) init52; // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_complete*) init53; // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_complete*) init54; // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_complete*) init55; // expected-error {{init methods must return a type related to the receiver type}} +@end +@implementation Test8 +- (id) init00 { return 0; } +- (id) init10 { return 0; } // expected-error {{method implementation does not match its declaration}} +- (id) init20 { return 0; } +- (id) init30 { return 0; } +- (id) init40 { return 0; } +- (id) init50 { return 0; } + +- (void) init01 {} // expected-error {{method was declared as an 'init' method, but its implementation doesn't match because its result type is not an object pointer}} +- (void) init11 {} +- (void) init21 {} // expected-error {{method was declared as an 'init' method, but its implementation doesn't match because its result type is not an object pointer}} +- (void) init31 {} // expected-error {{method was declared as an 'init' method, but its implementation doesn't match because its result type is not an object pointer}} +- (void) init41 {} // expected-error {{method was declared as an 'init' method, but its implementation doesn't match because its result type is not an object pointer}} +- (void) init51 {} + +- (Test8_incomplete*) init02 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_incomplete*) init12 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_incomplete*) init22 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_incomplete*) init32 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_incomplete*) init42 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_incomplete*) init52 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} + +- (Test8_super*) init03 { return 0; } +- (Test8_super*) init13 { return 0; } // expected-error {{method implementation does not match its declaration}} +- (Test8_super*) init23 { return 0; } +- (Test8_super*) init33 { return 0; } +- (Test8_super*) init43 { return 0; } +- (Test8_super*) init53 { return 0; } + +- (Test8*) init04 { return 0; } +- (Test8*) init14 { return 0; } // expected-error {{method implementation does not match its declaration}} +- (Test8*) init24 { return 0; } +- (Test8*) init34 { return 0; } +- (Test8*) init44 { return 0; } +- (Test8*) init54 { return 0; } + +- (Test8_complete*) init05 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_complete*) init15 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_complete*) init25 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_complete*) init35 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_complete*) init45 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_complete*) init55 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} +@end + +@class Test9_incomplete; +@interface Test9 +- (Test9_incomplete*) init1; // expected-error {{init methods must return a type related to the receiver type}} +- (Test9_incomplete*) init2; +@end +id test9(Test9 *v) { + return [v init1]; +} + +// rdar://9491791 +void rdar9491791(int p) { + switch (p) { + case 3:; + NSObject *o = [[NSObject alloc] init]; // expected-note {{jump bypasses initialization of retaining variable}} + [o release]; + break; + default: // expected-error {{switch case is in protected scope}} + break; + } +} + +#define RELEASE_MACRO(x) do { [x release]; } while(1) + +// rdar://9504750 +void rdar9504750(id p) { + RELEASE_MACRO(p); // expected-error {{ARC forbids explicit message send of 'release'}} +} diff --git a/test/ARCMT/cxx-checking.mm b/test/ARCMT/cxx-checking.mm new file mode 100644 index 0000000000..cf47bba0c6 --- /dev/null +++ b/test/ARCMT/cxx-checking.mm @@ -0,0 +1,105 @@ +// RUN: arcmt-test -check-only -verify --args -Warc-abi %s + +// Classes that have an Objective-C object pointer. +struct HasObjectMember0 { // expected-warning{{'HasObjectMember0' cannot be shared between ARC and non-ARC code; add a copy constructor, a copy assignment operator, and a destructor to make it ABI-compatible}} + id x; +}; + +struct HasObjectMember1 { // expected-warning{{'HasObjectMember1' cannot be shared between ARC and non-ARC code; add a copy constructor, a copy assignment operator, and a destructor to make it ABI-compatible}} + id x[3]; +}; + +struct HasObjectMember2 { // expected-warning{{'HasObjectMember2' cannot be shared between ARC and non-ARC code; add a copy constructor, a copy assignment operator, and a destructor to make it ABI-compatible}} + id x[3][2]; +}; + +// Don't complain if the type has non-external linkage +namespace { + struct HasObjectMember3 { + id x[3][2]; + }; +} + +// Don't complain if the Objective-C pointer type was explicitly given +// no lifetime. +struct HasObjectMember3 { + __unsafe_unretained id x[3][2]; +}; + +struct HasBlockPointerMember0 { // expected-warning{{'HasBlockPointerMember0' cannot be shared between ARC and non-ARC code; add a copy constructor, a copy assignment operator, and a destructor to make it ABI-compatible}} + int (^bp)(int); +}; + +struct HasBlockPointerMember1 { // expected-warning{{'HasBlockPointerMember1' cannot be shared between ARC and non-ARC code; add a copy constructor, a copy assignment operator, and a destructor to make it ABI-compatible}} + int (^bp[2][3])(int); +}; + +struct NonPOD { + NonPOD(const NonPOD&); +}; + +struct HasObjectMemberAndNonPOD0 { // expected-warning{{'HasObjectMemberAndNonPOD0' cannot be shared between ARC and non-ARC code; add a non-trivial copy assignment operator to make it ABI-compatible}} \ + // expected-warning{{'HasObjectMemberAndNonPOD0' cannot be shared between ARC and non-ARC code; add a non-trivial destructor to make it ABI-compatible}} + id x; + NonPOD np; +}; + +struct HasObjectMemberAndNonPOD1 { // expected-warning{{'HasObjectMemberAndNonPOD1' cannot be shared between ARC and non-ARC code; add a non-trivial copy assignment operator to make it ABI-compatible}} \ + // expected-warning{{'HasObjectMemberAndNonPOD1' cannot be shared between ARC and non-ARC code; add a non-trivial destructor to make it ABI-compatible}} + NonPOD np; + id x[3]; +}; + +struct HasObjectMemberAndNonPOD2 { // expected-warning{{'HasObjectMemberAndNonPOD2' cannot be shared between ARC and non-ARC code; add a non-trivial copy assignment operator to make it ABI-compatible}} \ + // expected-warning{{'HasObjectMemberAndNonPOD2' cannot be shared between ARC and non-ARC code; add a non-trivial destructor to make it ABI-compatible}} + NonPOD np; + id x[3][2]; +}; + +struct HasObjectMemberAndNonPOD3 { + HasObjectMemberAndNonPOD3 &operator=(const HasObjectMemberAndNonPOD3&); + ~HasObjectMemberAndNonPOD3(); + NonPOD np; + id x[3][2]; +}; + +struct HasBlockPointerMemberAndNonPOD0 { // expected-warning{{'HasBlockPointerMemberAndNonPOD0' cannot be shared between ARC and non-ARC code; add a non-trivial copy assignment operator to make it ABI-compatible}} \ +// expected-warning{{'HasBlockPointerMemberAndNonPOD0' cannot be shared between ARC and non-ARC code; add a non-trivial destructor to make it ABI-compatible}} + NonPOD np; + int (^bp)(int); +}; + +struct HasBlockPointerMemberAndNonPOD1 { // expected-warning{{'HasBlockPointerMemberAndNonPOD1' cannot be shared between ARC and non-ARC code; add a non-trivial copy assignment operator to make it ABI-compatible}} \ +// expected-warning{{'HasBlockPointerMemberAndNonPOD1' cannot be shared between ARC and non-ARC code; add a non-trivial destructor to make it ABI-compatible}} + NonPOD np; + int (^bp[2][3])(int); +}; + +int check_non_pod_objc_pointer0[__is_pod(id)? -1 : 1]; +int check_non_pod_objc_pointer1[__is_pod(__strong id)? -1 : 1]; +int check_non_pod_objc_pointer2[__is_pod(__unsafe_unretained id)? 1 : -1]; +int check_non_pod_objc_pointer3[__is_pod(id[2][3])? -1 : 1]; +int check_non_pod_objc_pointer4[__is_pod(__unsafe_unretained id[2][3])? 1 : -1]; +int check_non_pod_block0[__is_pod(int (^)(int))? -1 : 1]; +int check_non_pod_block1[__is_pod(int (^ __unsafe_unretained)(int))? 1 : -1]; + +struct FlexibleArrayMember0 { + int length; + id array[]; // expected-error{{flexible array member 'array' of non-POD element type 'id __strong[]'}} +}; + +struct FlexibleArrayMember1 { + int length; + __unsafe_unretained id array[]; +}; + +// It's okay to pass a retainable type through an ellipsis. +void variadic(...); +void test_variadic() { + variadic(1, 17, @"Foo"); +} + +// It's okay to create a VLA of retainable types. +void vla(int n) { + id vla[n]; +} diff --git a/test/ARCMT/dealloc.m b/test/ARCMT/dealloc.m new file mode 100644 index 0000000000..6166c426fd --- /dev/null +++ b/test/ARCMT/dealloc.m @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -arch x86_64 %s > %t +// RUN: diff %t %s.result + +@interface A +- (id)retain; +- (id)autorelease; +- (oneway void)release; +- (void)dealloc; +@end + +void test1(A *a) { + [a dealloc]; +} + +@interface Test2 : A +- (void) dealloc; +@end + +@implementation Test2 +- (void) dealloc { + [super dealloc]; +} +@end diff --git a/test/ARCMT/dealloc.m.result b/test/ARCMT/dealloc.m.result new file mode 100644 index 0000000000..445d91a8b7 --- /dev/null +++ b/test/ARCMT/dealloc.m.result @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -arch x86_64 %s > %t +// RUN: diff %t %s.result + +@interface A +- (id)retain; +- (id)autorelease; +- (oneway void)release; +- (void)dealloc; +@end + +void test1(A *a) { +} + +@interface Test2 : A +- (void) dealloc; +@end + +@implementation Test2 +@end diff --git a/test/ARCMT/init.m b/test/ARCMT/init.m new file mode 100644 index 0000000000..419288c355 --- /dev/null +++ b/test/ARCMT/init.m @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -arch x86_64 %s > %t +// RUN: diff %t %s.result + +@interface NSObject +-init; +@end + +@interface A : NSObject +-init; +-init2; +-foo; ++alloc; +@end + +@implementation A +-(id) init { + [self init]; + id a; + [a init]; + a = [[A alloc] init]; + + return self; +} + +-(id) init2 { + [super init]; + return self; +} + +-(id) foo { + [self init]; + [super init]; + + return self; +} +@end diff --git a/test/ARCMT/init.m.result b/test/ARCMT/init.m.result new file mode 100644 index 0000000000..9142c37a2f --- /dev/null +++ b/test/ARCMT/init.m.result @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -arch x86_64 %s > %t +// RUN: diff %t %s.result + +@interface NSObject +-init; +@end + +@interface A : NSObject +-init; +-init2; +-foo; ++alloc; +@end + +@implementation A +-(id) init { + self = [self init]; + id a; + [a init]; + a = [[A alloc] init]; + + return self; +} + +-(id) init2 { + self = [super init]; + return self; +} + +-(id) foo { + [self init]; + [super init]; + + return self; +} +@end diff --git a/test/ARCMT/nonobjc-to-objc-cast-2.m b/test/ARCMT/nonobjc-to-objc-cast-2.m new file mode 100644 index 0000000000..dba5227fae --- /dev/null +++ b/test/ARCMT/nonobjc-to-objc-cast-2.m @@ -0,0 +1,14 @@ +// RUN: arcmt-test -check-only -verify --args %s + +typedef int BOOL; +typedef const struct __CFString * CFStringRef; + +@class NSString; + +void f(BOOL b) { + CFStringRef cfstr; + 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 __bridge_transfer to transfer ownership of a +1 'CFStringRef' (aka 'const struct __CFString *') into ARC}} + void *vp = str; // expected-error {{disallowed}} +} diff --git a/test/ARCMT/nonobjc-to-objc-cast.m b/test/ARCMT/nonobjc-to-objc-cast.m new file mode 100644 index 0000000000..1fbe73f359 --- /dev/null +++ b/test/ARCMT/nonobjc-to-objc-cast.m @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -arch x86_64 %s > %t +// RUN: diff %t %s.result + +#include "Common.h" + +@interface NSString : NSObject +@end + +typedef const struct __CFString * CFStringRef; +extern const CFStringRef kUTTypePlainText; +extern const CFStringRef kUTTypeRTF; + +typedef const struct __CFAllocator * CFAllocatorRef; +typedef const struct __CFUUID * CFUUIDRef; + +extern const CFAllocatorRef kCFAllocatorDefault; + +extern CFStringRef CFUUIDCreateString(CFAllocatorRef alloc, CFUUIDRef uuid); + +void f(BOOL b, id p) { + NSString *str = (NSString *)kUTTypePlainText; + str = b ? kUTTypeRTF : kUTTypePlainText; + str = (NSString *)(b ? kUTTypeRTF : kUTTypePlainText); + str = (NSString *)p; // no change. + + // FIXME: Add objc -> c examples that we can handle. + + CFUUIDRef _uuid; + NSString *_uuidString = (NSString *)CFUUIDCreateString(kCFAllocatorDefault, _uuid); + _uuidString = [(NSString *)CFUUIDCreateString(kCFAllocatorDefault, _uuid) autorelease]; +} diff --git a/test/ARCMT/nonobjc-to-objc-cast.m.result b/test/ARCMT/nonobjc-to-objc-cast.m.result new file mode 100644 index 0000000000..856b80f8d9 --- /dev/null +++ b/test/ARCMT/nonobjc-to-objc-cast.m.result @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -arch x86_64 %s > %t +// RUN: diff %t %s.result + +#include "Common.h" + +@interface NSString : NSObject +@end + +typedef const struct __CFString * CFStringRef; +extern const CFStringRef kUTTypePlainText; +extern const CFStringRef kUTTypeRTF; + +typedef const struct __CFAllocator * CFAllocatorRef; +typedef const struct __CFUUID * CFUUIDRef; + +extern const CFAllocatorRef kCFAllocatorDefault; + +extern CFStringRef CFUUIDCreateString(CFAllocatorRef alloc, CFUUIDRef uuid); + +void f(BOOL b, id p) { + NSString *str = (__bridge NSString *)kUTTypePlainText; + str = (__bridge NSString *)(b ? kUTTypeRTF : kUTTypePlainText); + str = (__bridge NSString *)(b ? kUTTypeRTF : kUTTypePlainText); + str = (NSString *)p; // no change. + + // FIXME: Add objc -> c examples that we can handle. + + CFUUIDRef _uuid; + NSString *_uuidString = (__bridge_transfer NSString *)CFUUIDCreateString(kCFAllocatorDefault, _uuid); + _uuidString = (__bridge_transfer NSString *)CFUUIDCreateString(kCFAllocatorDefault, _uuid); +} diff --git a/test/ARCMT/releases.m b/test/ARCMT/releases.m new file mode 100644 index 0000000000..ddcdf93f32 --- /dev/null +++ b/test/ARCMT/releases.m @@ -0,0 +1,80 @@ +// RUN: %clang_cc1 -fobjc-nonfragile-abi -fblocks -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -arch x86_64 %s > %t +// RUN: diff %t %s.result + +typedef int BOOL; + +id IhaveSideEffect(); + +@protocol NSObject +- (BOOL)isEqual:(id)object; +- (id)retain; +- (oneway void)release; +@end + +@interface NSObject <NSObject> {} +@end + +@interface Foo : NSObject { + id bar; +} +@property (retain) id bar; +-(void)test:(id)obj; +@end + +@implementation Foo + +@synthesize bar; + +-(void)test:(id)obj { + id x = self.bar; + [x retain]; + self.bar = obj; + // do stuff with x; + [x release]; + + [IhaveSideEffect() release]; + + [x release], x = 0; +} + +@end + +void func(Foo *p) { + [p release]; + (([p release])); +} + +@interface Baz { + id <NSObject> _foo; +} +@end + +@implementation Baz +- dealloc { + [_foo release]; + return 0; +} +@end + +void block_test(Foo *p) { + id (^B)() = ^() { + if (p) { + id (^IB)() = ^() { + id bar = [p retain]; + [p release]; + return bar; + }; + IB(); + } + return [p retain]; + }; +} + +#define RELEASE_MACRO(x) [x release] +#define RELEASE_MACRO2(x) RELEASE_MACRO(x) + +void test2(id p) { + RELEASE_MACRO(p); + RELEASE_MACRO2(p); +} diff --git a/test/ARCMT/releases.m.result b/test/ARCMT/releases.m.result new file mode 100644 index 0000000000..b502cbb91d --- /dev/null +++ b/test/ARCMT/releases.m.result @@ -0,0 +1,72 @@ +// RUN: %clang_cc1 -fobjc-nonfragile-abi -fblocks -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -arch x86_64 %s > %t +// RUN: diff %t %s.result + +typedef int BOOL; + +id IhaveSideEffect(); + +@protocol NSObject +- (BOOL)isEqual:(id)object; +- (id)retain; +- (oneway void)release; +@end + +@interface NSObject <NSObject> {} +@end + +@interface Foo : NSObject { + id bar; +} +@property (retain) id bar; +-(void)test:(id)obj; +@end + +@implementation Foo + +@synthesize bar; + +-(void)test:(id)obj { + id x = self.bar; + self.bar = obj; + // do stuff with x; + + IhaveSideEffect(); + + x = 0; +} + +@end + +void func(Foo *p) { +} + +@interface Baz { + id <NSObject> _foo; +} +@end + +@implementation Baz +- dealloc { + return 0; +} +@end + +void block_test(Foo *p) { + id (^B)() = ^() { + if (p) { + id (^IB)() = ^() { + id bar = p; + return bar; + }; + IB(); + } + return p; + }; +} + +#define RELEASE_MACRO(x) [x release] +#define RELEASE_MACRO2(x) RELEASE_MACRO(x) + +void test2(id p) { +} diff --git a/test/ARCMT/remove-dealloc-method.m b/test/ARCMT/remove-dealloc-method.m new file mode 100644 index 0000000000..7689bc0a13 --- /dev/null +++ b/test/ARCMT/remove-dealloc-method.m @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -arch x86_64 %s > %t +// RUN: diff %t %s.result + +#define nil ((void*) 0) + +@interface Foo +@property (retain) id x; +@property (retain) id y; +@property (retain) id w; +@property (retain) id z; +@end + +@implementation Foo +@synthesize x; +@synthesize y; +@synthesize w; +@synthesize z; + +- (void) dealloc { + self.x = 0; + [self setY:nil]; + w = nil; + self.z = nil; +} +@end diff --git a/test/ARCMT/remove-dealloc-method.m.result b/test/ARCMT/remove-dealloc-method.m.result new file mode 100644 index 0000000000..d423243a8f --- /dev/null +++ b/test/ARCMT/remove-dealloc-method.m.result @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -arch x86_64 %s > %t +// RUN: diff %t %s.result + +#define nil ((void*) 0) + +@interface Foo +@property (retain) id x; +@property (retain) id y; +@property (retain) id w; +@property (retain) id z; +@end + +@implementation Foo +@synthesize x; +@synthesize y; +@synthesize w; +@synthesize z; + +@end diff --git a/test/ARCMT/remove-dealloc-zerouts.m b/test/ARCMT/remove-dealloc-zerouts.m new file mode 100644 index 0000000000..7bd00a3618 --- /dev/null +++ b/test/ARCMT/remove-dealloc-zerouts.m @@ -0,0 +1,44 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -arch x86_64 %s > %t +// RUN: diff %t %s.result + +@interface Foo +@property (retain) id x; +@property (retain) id y; +@property (retain) id w; +@property (retain) id z; +@property (strong) id q; +@end + +@implementation Foo +@synthesize x; +@synthesize y; +@synthesize w; +@synthesize q; +@dynamic z; + +- (void) dealloc { + self.x = self.y = self.w = 0; + self.x = 0, w = 0, y = 0; + [self setY:0]; + w = 0; + q = 0; + self.z = 0; +} +@end + +@interface Bar +@property (retain) Foo *a; +- (void) setA:(Foo*) val; +- (id) a; +@end + +@implementation Bar +- (void) dealloc { + [self setA:0]; // This is user-defined setter overriding synthesize, don't touch it. + self.a.x = 0; // every dealloc must zero out its own ivar. This patter is not recognized. +} +@synthesize a; +- (void) setA:(Foo*) val { } +- (id) a {return 0;} +@end diff --git a/test/ARCMT/remove-dealloc-zerouts.m.result b/test/ARCMT/remove-dealloc-zerouts.m.result new file mode 100644 index 0000000000..ba93b3f088 --- /dev/null +++ b/test/ARCMT/remove-dealloc-zerouts.m.result @@ -0,0 +1,39 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -arch x86_64 %s > %t +// RUN: diff %t %s.result + +@interface Foo +@property (retain) id x; +@property (retain) id y; +@property (retain) id w; +@property (retain) id z; +@property (strong) id q; +@end + +@implementation Foo +@synthesize x; +@synthesize y; +@synthesize w; +@synthesize q; +@dynamic z; + +- (void) dealloc { + self.z = 0; +} +@end + +@interface Bar +@property (retain) Foo *a; +- (void) setA:(Foo*) val; +- (id) a; +@end + +@implementation Bar +- (void) dealloc { + [self setA:0]; // This is user-defined setter overriding synthesize, don't touch it. + self.a.x = 0; // every dealloc must zero out its own ivar. This patter is not recognized. +} +@synthesize a; +- (void) setA:(Foo*) val { } +- (id) a {return 0;} +@end diff --git a/test/ARCMT/remove-statements.m b/test/ARCMT/remove-statements.m new file mode 100644 index 0000000000..6fb08a7cc2 --- /dev/null +++ b/test/ARCMT/remove-statements.m @@ -0,0 +1,45 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -arch x86_64 %s > %t +// RUN: diff %t %s.result + +#include "Common.h" + +@interface myController : NSObject +-(id)test:(id)x; +@end + +#define MY_MACRO1(x) +#define MY_MACRO2(x) (void)x + +@implementation myController +-(id) test:(id) x { + [[x retain] autorelease]; + return [[x retain] autorelease]; +} + +-(void)dealloc +{ + id array, array_already_empty; + for (id element in array_already_empty) { + } + + [array release]; + ; + + int b, b_array_already_empty; + if (b) + [array release]; + if (b_array_already_empty) ; + + if (b) { + [array release]; + } + if (b_array_already_empty) { + } + + if (b) + MY_MACRO1(array); + if (b) + MY_MACRO2(array); +} +@end diff --git a/test/ARCMT/remove-statements.m.result b/test/ARCMT/remove-statements.m.result new file mode 100644 index 0000000000..ab3390f9e8 --- /dev/null +++ b/test/ARCMT/remove-statements.m.result @@ -0,0 +1,38 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -arch x86_64 %s > %t +// RUN: diff %t %s.result + +#include "Common.h" + +@interface myController : NSObject +-(id)test:(id)x; +@end + +#define MY_MACRO1(x) +#define MY_MACRO2(x) (void)x + +@implementation myController +-(id) test:(id) x { + return x; +} + +-(void)dealloc +{ + id array, array_already_empty; + for (id element in array_already_empty) { + } + + ; + + int b, b_array_already_empty; + if (b_array_already_empty) ; + + if (b_array_already_empty) { + } + + if (b) + MY_MACRO1(array); + if (b) + MY_MACRO2(array); +} +@end diff --git a/test/ARCMT/retains.m b/test/ARCMT/retains.m new file mode 100644 index 0000000000..c251f88682 --- /dev/null +++ b/test/ARCMT/retains.m @@ -0,0 +1,71 @@ +// RUN: %clang_cc1 -fobjc-nonfragile-abi -fblocks -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -arch x86_64 %s > %t +// RUN: diff %t %s.result + +#include "Common.h" + +id IhaveSideEffect(); + +@interface Foo : NSObject { + id bar; +} +@property (retain) id bar; +-(id)test:(id)obj; +-(id)something; +@end + +#define Something_Macro(key, comment) \ + [[Foo new] something] + +@implementation Foo + +@synthesize bar; + +-(id)something {} + +-(id)test:(id)obj { + id x = self.bar; + [x retain]; + self.bar = obj; + if (obj) + [obj retain]; + + [Something_Macro(@"foo", "@bar") retain]; + + [IhaveSideEffect() retain]; + + [[self something] retain]; + + [[self retain] something]; + + [[IhaveSideEffect() retain] autorelease]; + [[x retain] autorelease]; + // do stuff with x; + [x release]; + return [self retain]; +} + +- (id)test1 { + id x=0; + ([x retain]); + return ((([x retain]))); +} +@end + +id foo (Foo *p) { + p = [p retain]; + return ([p retain]); +} + +void block_tests(Foo *p) { + id (^B)() = ^() { + if (p) { + id (^IB)() = ^() { + id bar = [p retain]; + return bar; + }; + IB(); + } + return [p retain]; + }; +} diff --git a/test/ARCMT/retains.m.result b/test/ARCMT/retains.m.result new file mode 100644 index 0000000000..b8f625a91c --- /dev/null +++ b/test/ARCMT/retains.m.result @@ -0,0 +1,65 @@ +// RUN: %clang_cc1 -fobjc-nonfragile-abi -fblocks -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -arch x86_64 %s > %t +// RUN: diff %t %s.result + +#include "Common.h" + +id IhaveSideEffect(); + +@interface Foo : NSObject { + id bar; +} +@property (retain) id bar; +-(id)test:(id)obj; +-(id)something; +@end + +#define Something_Macro(key, comment) \ + [[Foo new] something] + +@implementation Foo + +@synthesize bar; + +-(id)something {} + +-(id)test:(id)obj { + id x = self.bar; + self.bar = obj; + + Something_Macro(@"foo", "@bar"); + + IhaveSideEffect(); + + [self something]; + + [self something]; + + IhaveSideEffect(); + // do stuff with x; + return self; +} + +- (id)test1 { + id x=0; + return (((x))); +} +@end + +id foo (Foo *p) { + p = p; + return (p); +} + +void block_tests(Foo *p) { + id (^B)() = ^() { + if (p) { + id (^IB)() = ^() { + id bar = p; + return bar; + }; + IB(); + } + return p; + }; +} diff --git a/test/ARCMT/rewrite-block-var.m b/test/ARCMT/rewrite-block-var.m new file mode 100644 index 0000000000..70da6786c0 --- /dev/null +++ b/test/ARCMT/rewrite-block-var.m @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fblocks -fsyntax-only -fobjc-arc -x objective-c %s.result -D__IPHONE_OS_VERSION_MIN_REQUIRED=50000 +// RUN: arcmt-test --args -arch x86_64 %s -D__IPHONE_OS_VERSION_MIN_REQUIRED=50000 > %t +// RUN: diff %t %s.result + +#include "Common.h" + +@interface Foo : NSObject +-(Foo *)something; +@end + +void bar(void (^block)()); + +void test1(Foo *p) { + __block Foo *x = p; // __block used just to break cycle. + bar(^{ + [x something]; + }); +} + +void test2(Foo *p) { + __block Foo *x; // __block used as output variable. + bar(^{ + x = [p something]; + }); +} diff --git a/test/ARCMT/rewrite-block-var.m.result b/test/ARCMT/rewrite-block-var.m.result new file mode 100644 index 0000000000..a37e6af5c4 --- /dev/null +++ b/test/ARCMT/rewrite-block-var.m.result @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fblocks -fsyntax-only -fobjc-arc -x objective-c %s.result -D__IPHONE_OS_VERSION_MIN_REQUIRED=50000 +// RUN: arcmt-test --args -arch x86_64 %s -D__IPHONE_OS_VERSION_MIN_REQUIRED=50000 > %t +// RUN: diff %t %s.result + +#include "Common.h" + +@interface Foo : NSObject +-(Foo *)something; +@end + +void bar(void (^block)()); + +void test1(Foo *p) { + __weak Foo *x = p; // __block used just to break cycle. + bar(^{ + [x something]; + }); +} + +void test2(Foo *p) { + __block Foo *x; // __block used as output variable. + bar(^{ + x = [p something]; + }); +} diff --git a/test/ARCMT/safe-arc-assign.m b/test/ARCMT/safe-arc-assign.m new file mode 100644 index 0000000000..2b8f93e51b --- /dev/null +++ b/test/ARCMT/safe-arc-assign.m @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -arch x86_64 %s > %t +// RUN: diff %t %s.result + +void test12(id collection) { + for (id x in collection) { + x = 0; + x = 0; + } + + for (__strong id x in collection) { + x = 0; + } +} diff --git a/test/ARCMT/safe-arc-assign.m.result b/test/ARCMT/safe-arc-assign.m.result new file mode 100644 index 0000000000..eac3d62eb1 --- /dev/null +++ b/test/ARCMT/safe-arc-assign.m.result @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -arch x86_64 %s > %t +// RUN: diff %t %s.result + +void test12(id collection) { + for (__strong id x in collection) { + x = 0; + x = 0; + } + + for (__strong id x in collection) { + x = 0; + } +} diff --git a/test/ARCMT/with-working-dir.m b/test/ARCMT/with-working-dir.m new file mode 100644 index 0000000000..ebfd900378 --- /dev/null +++ b/test/ARCMT/with-working-dir.m @@ -0,0 +1,47 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -working-directory %S with-working-dir.m > %t +// RUN: diff %t %s.result + +typedef int BOOL; +id IhaveSideEffect(); + +@protocol NSObject +- (BOOL)isEqual:(id)object; +- (id)retain; +- (oneway void)release; +- (id)something; +@end + +@interface NSObject <NSObject> {} +@end + +@interface Foo : NSObject { + id bar; +} +@property (retain) id bar; +-(id)test:(id)obj; +@end + +@implementation Foo + +@synthesize bar; + +-(id)test:(id)obj { + id x = self.bar; + [x retain]; + self.bar = obj; + if (obj) + [obj retain]; + + [IhaveSideEffect() retain]; + + [[self something] retain]; + + [[self retain] something]; + + // do stuff with x; + [x release]; + return [self retain]; +} + +@end diff --git a/test/ARCMT/with-working-dir.m.result b/test/ARCMT/with-working-dir.m.result new file mode 100644 index 0000000000..19cdec48aa --- /dev/null +++ b/test/ARCMT/with-working-dir.m.result @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -x objective-c %s.result +// RUN: arcmt-test --args -working-directory %S with-working-dir.m > %t +// RUN: diff %t %s.result + +typedef int BOOL; +id IhaveSideEffect(); + +@protocol NSObject +- (BOOL)isEqual:(id)object; +- (id)retain; +- (oneway void)release; +- (id)something; +@end + +@interface NSObject <NSObject> {} +@end + +@interface Foo : NSObject { + id bar; +} +@property (retain) id bar; +-(id)test:(id)obj; +@end + +@implementation Foo + +@synthesize bar; + +-(id)test:(id)obj { + id x = self.bar; + self.bar = obj; + + IhaveSideEffect(); + + [self something]; + + [self something]; + + // do stuff with x; + return self; +} + +@end |