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
diff --git a/test/ARCMT/atautorelease-check.m b/test/ARCMT/atautorelease-check.m
new file mode 100644
index 0000000..126642cd
--- /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}}
+}