]> git.saurik.com Git - apple/objc4.git/blob - test/rr-autorelease-fastarc.m
objc4-680.tar.gz
[apple/objc4.git] / test / rr-autorelease-fastarc.m
1 // TEST_CFLAGS -Os -framework Foundation
2 // TEST_DISABLED pending clang support for rdar://20530049
3
4 #include "test.h"
5 #include "testroot.i"
6
7 #if __i386__
8
9 int main()
10 {
11 // no optimization on i386 (neither Mac nor Simulator)
12 succeed(__FILE__);
13 }
14
15 #else
16
17 #include <objc/objc-internal.h>
18 #include <objc/objc-abi.h>
19 #include <Foundation/Foundation.h>
20
21 @interface TestObject : TestRoot @end
22 @implementation TestObject @end
23
24
25 #ifdef __arm__
26 # define MAGIC asm volatile("mov r7, r7")
27 # define NOT_MAGIC asm volatile("mov r6, r6")
28 #elif __arm64__
29 # define MAGIC asm volatile("mov x29, x29")
30 # define NOT_MAGIC asm volatile("mov x28, x28")
31 #elif __x86_64__
32 # define MAGIC asm volatile("")
33 # define NOT_MAGIC asm volatile("nop")
34 #else
35 # error unknown architecture
36 #endif
37
38
39 @interface Tester : NSObject @end
40 @implementation Tester {
41 @public
42 id ivar;
43 }
44
45 -(id) return0 {
46 return ivar;
47 }
48 -(id) return1 {
49 id x = ivar;
50 [x self];
51 return x;
52 }
53
54 @end
55
56 OBJC_EXPORT
57 id
58 objc_retainAutoreleasedReturnValue(id obj)
59 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
60
61 // Accept a value returned through a +0 autoreleasing convention for use at +0.
62 OBJC_EXPORT
63 id
64 objc_unsafeClaimAutoreleasedReturnValue(id obj)
65 __OSX_AVAILABLE_STARTING(__MAC_10_11, __IPHONE_9_0);
66
67
68 int
69 main()
70 {
71 TestObject *obj;
72 Tester *tt = [Tester new];
73
74 #ifdef __x86_64__
75 // need to get DYLD to resolve the stubs on x86
76 PUSH_POOL {
77 TestObject *warm_up = [[TestObject alloc] init];
78 testassert(warm_up);
79 warm_up = objc_retainAutoreleasedReturnValue(warm_up);
80 warm_up = objc_unsafeClaimAutoreleasedReturnValue(warm_up);
81 warm_up = nil;
82 } POP_POOL;
83 #endif
84
85 testprintf(" Successful +1 -> +1 handshake\n");
86
87 PUSH_POOL {
88 obj = [[TestObject alloc] init];
89 testassert(obj);
90 tt->ivar = obj;
91 obj = nil;
92
93 TestRootRetain = 0;
94 TestRootRelease = 0;
95 TestRootAutorelease = 0;
96 TestRootDealloc = 0;
97
98 TestObject *tmp = [tt return1];
99
100 testassert(TestRootDealloc == 0);
101 testassert(TestRootRetain == 1);
102 testassert(TestRootRelease == 0);
103 testassert(TestRootAutorelease == 0);
104
105 tt->ivar = nil;
106 testassert(TestRootDealloc == 0);
107 testassert(TestRootRetain == 1);
108 testassert(TestRootRelease == 1);
109 testassert(TestRootAutorelease == 0);
110
111 tmp = nil;
112 testassert(TestRootDealloc == 1);
113 testassert(TestRootRetain == 1);
114 testassert(TestRootRelease == 2);
115 testassert(TestRootAutorelease == 0);
116
117 } POP_POOL;
118
119 testprintf(" Successful +0 -> +0 handshake\n");
120
121 PUSH_POOL {
122 obj = [[TestObject alloc] init];
123 testassert(obj);
124 tt->ivar = obj;
125 obj = nil;
126
127 TestRootRetain = 0;
128 TestRootRelease = 0;
129 TestRootAutorelease = 0;
130 TestRootDealloc = 0;
131
132 __unsafe_unretained TestObject *tmp = [tt return0];
133
134 testassert(TestRootDealloc == 0);
135 testassert(TestRootRetain == 0);
136 testassert(TestRootRelease == 0);
137 testassert(TestRootAutorelease == 0);
138
139 tmp = nil;
140 testassert(TestRootDealloc == 0);
141 testassert(TestRootRetain == 0);
142 testassert(TestRootRelease == 0);
143 testassert(TestRootAutorelease == 0);
144
145 tt->ivar = nil;
146 testassert(TestRootDealloc == 1);
147 testassert(TestRootRetain == 0);
148 testassert(TestRootRelease == 1);
149 testassert(TestRootAutorelease == 0);
150
151 } POP_POOL;
152
153
154 testprintf(" Successful +1 -> +0 handshake\n");
155
156 PUSH_POOL {
157 obj = [[TestObject alloc] init];
158 testassert(obj);
159 tt->ivar = obj;
160 obj = nil;
161
162 TestRootRetain = 0;
163 TestRootRelease = 0;
164 TestRootAutorelease = 0;
165 TestRootDealloc = 0;
166
167 __unsafe_unretained TestObject *tmp = [tt return1];
168
169 testassert(TestRootDealloc == 0);
170 testassert(TestRootRetain == 1);
171 testassert(TestRootRelease == 1);
172 testassert(TestRootAutorelease == 0);
173
174 tmp = nil;
175 testassert(TestRootDealloc == 0);
176 testassert(TestRootRetain == 1);
177 testassert(TestRootRelease == 1);
178 testassert(TestRootAutorelease == 0);
179
180 tt->ivar = nil;
181 testassert(TestRootDealloc == 1);
182 testassert(TestRootRetain == 1);
183 testassert(TestRootRelease == 2);
184 testassert(TestRootAutorelease == 0);
185
186 } POP_POOL;
187
188
189 testprintf(" Successful +0 -> +1 handshake\n");
190
191 PUSH_POOL {
192 obj = [[TestObject alloc] init];
193 testassert(obj);
194 tt->ivar = obj;
195 obj = nil;
196
197 TestRootRetain = 0;
198 TestRootRelease = 0;
199 TestRootAutorelease = 0;
200 TestRootDealloc = 0;
201
202 TestObject *tmp = [tt return0];
203
204 testassert(TestRootDealloc == 0);
205 testassert(TestRootRetain == 1);
206 testassert(TestRootRelease == 0);
207 testassert(TestRootAutorelease == 0);
208
209 tmp = nil;
210 testassert(TestRootDealloc == 0);
211 testassert(TestRootRetain == 1);
212 testassert(TestRootRelease == 1);
213 testassert(TestRootAutorelease == 0);
214
215 tt->ivar = nil;
216 testassert(TestRootDealloc == 1);
217 testassert(TestRootRetain == 1);
218 testassert(TestRootRelease == 2);
219 testassert(TestRootAutorelease == 0);
220
221 } POP_POOL;
222
223
224
225 succeed(__FILE__);
226
227 return 0;
228 }
229
230
231 #endif