1// RUN: %clang_cc1 -arcmt-check -verify -triple x86_64-apple-darwin10 %s
2
3#if __has_feature(objc_arr)
4#define NS_AUTOMATED_REFCOUNT_UNAVAILABLE __attribute__((unavailable("not available in automatic reference counting mode")))
5#else
6#define NS_AUTOMATED_REFCOUNT_UNAVAILABLE
7#endif
8
9typedef struct _NSZone NSZone;
10typedef int BOOL;
11typedef unsigned NSUInteger;
12
13@protocol NSObject
14- (BOOL)isEqual:(id)object;
15- (id)retain NS_AUTOMATED_REFCOUNT_UNAVAILABLE;
16- (NSUInteger)retainCount NS_AUTOMATED_REFCOUNT_UNAVAILABLE;
17- (oneway void)release NS_AUTOMATED_REFCOUNT_UNAVAILABLE;
18- (id)autorelease NS_AUTOMATED_REFCOUNT_UNAVAILABLE;
19
20- (NSZone *)zone NS_AUTOMATED_REFCOUNT_UNAVAILABLE;
21@end
22
23@protocol NSCopying
24- (id)copyWithZone:(NSZone *)zone;
25@end
26
27@protocol NSMutableCopying
28- (id)mutableCopyWithZone:(NSZone *)zone;
29@end
30
31@interface NSObject <NSObject> {}
32- (id)init;
33
34+ (id)new;
35+ (id)allocWithZone:(NSZone *)zone NS_AUTOMATED_REFCOUNT_UNAVAILABLE;
36+ (id)alloc;
37- (void)dealloc;
38
39- (void)finalize;
40
41- (id)copy;
42- (id)mutableCopy;
43
44+ (id)copyWithZone:(NSZone *)zone NS_AUTOMATED_REFCOUNT_UNAVAILABLE;
45+ (id)mutableCopyWithZone:(NSZone *)zone NS_AUTOMATED_REFCOUNT_UNAVAILABLE;
46@end
47
48extern void NSRecycleZone(NSZone *zone);
49
50NS_AUTOMATED_REFCOUNT_UNAVAILABLE
51@interface NSAutoreleasePool : NSObject { // expected-note 13 {{marked unavailable here}}
52@private
53    void    *_token;
54    void    *_reserved3;
55    void    *_reserved2;
56    void    *_reserved;
57}
58
59+ (void)addObject:(id)anObject;
60
61- (void)addObject:(id)anObject;
62
63- (void)drain;
64
65@end
66
67
68void NSLog(id, ...);
69
70int main (int argc, const char * argv[]) {
71    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
72    NSAutoreleasePool *chunkPool = [[NSAutoreleasePool alloc] init]; // expected-error 2 {{'NSAutoreleasePool' is unavailable}}
73
74    while (argc) {
75      [chunkPool release];
76      // the following pool was not released in this scope, don't touch it.
77      chunkPool = [[NSAutoreleasePool alloc] init]; // expected-error {{'NSAutoreleasePool' is unavailable}}
78    }
79
80    [chunkPool drain];
81    [pool drain];
82
83    return 0;
84}
85
86void f(void) {
87    NSAutoreleasePool * pool;  // expected-error {{'NSAutoreleasePool' is unavailable}}
88
89    for (int i=0; i != 10; ++i) {
90      id x = pool; // We won't touch a NSAutoreleasePool if we can't safely
91                   // remove all the references to it.
92    }
93
94    pool = [[NSAutoreleasePool alloc] init];  // expected-error {{'NSAutoreleasePool' is unavailable}}
95    NSLog(@"%s", "YES");
96    [pool release];
97}
98
99void f2(void) {
100    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // expected-error 2 {{'NSAutoreleasePool' is unavailable}} \
101                                            // expected-note {{scope begins here}}
102
103    // 'x' is declared inside the "pool scope" but used outside it, if we create
104    // a @autorelease scope it will be undefined outside it so don't touch the pool.
105    int x = 0; // expected-note {{declared here}}
106
107    [pool release]; // expected-note {{scope ends here}}
108
109    ++x; // expected-error {{a name is referenced outside the NSAutoreleasePool scope that it was declared in}}
110}
111
112void f3(void) {
113    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // expected-error 2 {{'NSAutoreleasePool' is unavailable}} \
114                                            // expected-note {{scope begins here}}
115
116    struct S { int x; }; // expected-note {{declared here}}
117
118    [pool release]; // expected-note {{scope ends here}}
119
120    struct S *var; // expected-error {{a name is referenced outside the NSAutoreleasePool scope that it was declared in}}
121    var->x = 0;
122}
123
124void f4(void) {
125    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // expected-error 2 {{'NSAutoreleasePool' is unavailable}} \
126                                            // expected-note {{scope begins here}}
127
128    enum { Bar }; // expected-note {{declared here}}
129
130    [pool release]; // expected-note {{scope ends here}}
131
132    int x = Bar; // expected-error {{a name is referenced outside the NSAutoreleasePool scope that it was declared in}}
133}
134
135void f5(void) {
136    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // expected-error 2 {{'NSAutoreleasePool' is unavailable}} \
137                                            // expected-note {{scope begins here}}
138
139    typedef int Bar; // expected-note {{declared here}}
140
141    [pool release]; // expected-note {{scope ends here}}
142
143    Bar x; // expected-error {{a name is referenced outside the NSAutoreleasePool scope that it was declared in}}
144}
145