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