1/*
2 * Copyright (c) 2009 Apple Inc. All rights reserved.
3 *
4 * @APPLE_APACHE_LICENSE_HEADER_START@
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 *     http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 * @APPLE_APACHE_LICENSE_HEADER_END@
19 */
20//
21//  resurrect-global.m
22//  gctests
23//
24//  Created by Blaine Garst on 12/9/08.
25//  Copyright 2008 Apple. All rights reserved.
26//
27
28// CONFIG open GC -C99 runtime: auto_zone_resurrection_error
29
30#import <Foundation/Foundation.h>
31#import <objc/runtime.h>
32#import <objc/objc-auto.h>
33
34@interface TestObject : NSObject {
35@public
36    id string;
37    bool isGlobal;
38}
39- (void)makeGlobal;
40@end
41
42TestObject *global;
43int localDidFinalize = 0;
44int globalDidFinalize = 0;
45int Errors;
46
47@implementation TestObject
48
49- (void)finalize {
50    if (isGlobal) {
51        static int counter = 0;
52        if (counter++ == 0) {
53            objc_setAssociatedObject(
54                global,     // target
55                self,       // use self as key
56                self,       // use self (garbage) as value
57                OBJC_ASSOCIATION_RETAIN_NONATOMIC);
58            globalDidFinalize = 1;
59        }
60    }
61    else  {
62        static int counter = 0;
63        if (counter++ == 0) {
64            objc_setAssociatedObject(
65                global,     // target
66                self,       // use self as key
67                self,       // use self (garbage) as value
68                OBJC_ASSOCIATION_RETAIN_NONATOMIC);
69            localDidFinalize = 1;
70        }
71    }
72    [super finalize];
73}
74- (void)makeGlobal {
75    [[NSGarbageCollector defaultCollector] disableCollectorForPointer:self];
76    [[NSGarbageCollector defaultCollector] enableCollectorForPointer:self];
77    isGlobal = true;
78}
79@end
80
81
82int main(int argc, char *argv[]) {
83    global = [[TestObject alloc] init];
84
85#if 0
86    for (int i = 0; i < 101; ++i) [[TestObject alloc] init];
87    [[NSGarbageCollector defaultCollector] collectIfNeeded];
88    if (localDidFinalize == 0) {
89        printf("%s: Whoops, no locals were finalized!!\n", argv[0]);
90        ++Errors;
91    }
92#endif
93
94    for (int i = 0; i < 101; ++i) [[[TestObject alloc] init] makeGlobal];
95    [[NSGarbageCollector defaultCollector] collectExhaustively];
96    if (globalDidFinalize == 0) {
97        printf("%s: Whoops, no globals were finalized!!\n", argv[0]);
98        ++Errors;
99    }
100
101    if (Errors == 0) {
102        printf("%s: Success!\n", argv[0]);
103    }
104    return Errors;
105
106}
107