1// TEST_CONFIG MEM=mrc,arc
2
3#include "test.h"
4#include <objc/runtime.h>
5#include <objc/objc-abi.h>
6
7#include "testroot.i"
8
9@interface Base : TestRoot {
10  @public
11    id ivar;
12}
13@end
14@implementation Base @end
15
16int main()
17{
18    SEL _cmd = @selector(foo);
19    Base *o = [Base new];
20    ptrdiff_t offset = ivar_getOffset(class_getInstanceVariable([Base class], "ivar"));
21    testassert(offset == sizeof(id));
22
23    TestRoot *value = [TestRoot new];
24
25    // fixme test atomicity
26
27    // Original setter API
28
29    testprintf("original nonatomic retain\n");
30    o->ivar = nil;
31    TestRootRetain = 0;
32    TestRootCopyWithZone = 0;
33    TestRootMutableCopyWithZone = 0;
34    objc_setProperty(o, _cmd, offset, value, NO/*atomic*/, NO/*copy*/);
35    testassert(TestRootRetain == 1);
36    testassert(TestRootCopyWithZone == 0);
37    testassert(TestRootMutableCopyWithZone == 0);
38    testassert(o->ivar == value);
39
40    testprintf("original atomic retain\n");
41    o->ivar = nil;
42    TestRootRetain = 0;
43    TestRootCopyWithZone = 0;
44    TestRootMutableCopyWithZone = 0;
45    objc_setProperty(o, _cmd, offset, value, YES/*atomic*/, NO/*copy*/);
46    testassert(TestRootRetain == 1);
47    testassert(TestRootCopyWithZone == 0);
48    testassert(TestRootMutableCopyWithZone == 0);
49    testassert(o->ivar == value);
50
51    testprintf("original nonatomic copy\n");
52    o->ivar = nil;
53    TestRootRetain = 0;
54    TestRootCopyWithZone = 0;
55    TestRootMutableCopyWithZone = 0;
56    objc_setProperty(o, _cmd, offset, value, NO/*atomic*/, YES/*copy*/);
57    testassert(TestRootRetain == 0);
58    testassert(TestRootCopyWithZone == 1);
59    testassert(TestRootMutableCopyWithZone == 0);
60    testassert(o->ivar  &&  o->ivar != value);
61
62    testprintf("original atomic copy\n");
63    o->ivar = nil;
64    TestRootRetain = 0;
65    TestRootCopyWithZone = 0;
66    TestRootMutableCopyWithZone = 0;
67    objc_setProperty(o, _cmd, offset, value, YES/*atomic*/, YES/*copy*/);
68    testassert(TestRootRetain == 0);
69    testassert(TestRootCopyWithZone == 1);
70    testassert(TestRootMutableCopyWithZone == 0);
71    testassert(o->ivar  &&  o->ivar != value);
72
73    testprintf("original nonatomic mutablecopy\n");
74    o->ivar = nil;
75    TestRootRetain = 0;
76    TestRootCopyWithZone = 0;
77    TestRootMutableCopyWithZone = 0;
78    objc_setProperty(o, _cmd, offset, value, NO/*atomic*/, 2/*copy*/);
79    testassert(TestRootRetain == 0);
80    testassert(TestRootCopyWithZone == 0);
81    testassert(TestRootMutableCopyWithZone == 1);
82    testassert(o->ivar  &&  o->ivar != value);
83
84    testprintf("original atomic mutablecopy\n");
85    o->ivar = nil;
86    TestRootRetain = 0;
87    TestRootCopyWithZone = 0;
88    TestRootMutableCopyWithZone = 0;
89    objc_setProperty(o, _cmd, offset, value, YES/*atomic*/, 2/*copy*/);
90    testassert(TestRootRetain == 0);
91    testassert(TestRootCopyWithZone == 0);
92    testassert(TestRootMutableCopyWithZone == 1);
93    testassert(o->ivar  &&  o->ivar != value);
94
95
96    // Optimized setter API
97
98    testprintf("optimized nonatomic retain\n");
99    o->ivar = nil;
100    TestRootRetain = 0;
101    TestRootCopyWithZone = 0;
102    TestRootMutableCopyWithZone = 0;
103    objc_setProperty_nonatomic(o, _cmd, value, offset);
104    testassert(TestRootRetain == 1);
105    testassert(TestRootCopyWithZone == 0);
106    testassert(TestRootMutableCopyWithZone == 0);
107    testassert(o->ivar == value);
108
109    testprintf("optimized atomic retain\n");
110    o->ivar = nil;
111    TestRootRetain = 0;
112    TestRootCopyWithZone = 0;
113    TestRootMutableCopyWithZone = 0;
114    objc_setProperty_atomic(o, _cmd, value, offset);
115    testassert(TestRootRetain == 1);
116    testassert(TestRootCopyWithZone == 0);
117    testassert(TestRootMutableCopyWithZone == 0);
118    testassert(o->ivar == value);
119
120    testprintf("optimized nonatomic copy\n");
121    o->ivar = nil;
122    TestRootRetain = 0;
123    TestRootCopyWithZone = 0;
124    TestRootMutableCopyWithZone = 0;
125    objc_setProperty_nonatomic_copy(o, _cmd, value, offset);
126    testassert(TestRootRetain == 0);
127    testassert(TestRootCopyWithZone == 1);
128    testassert(TestRootMutableCopyWithZone == 0);
129    testassert(o->ivar  &&  o->ivar != value);
130
131    testprintf("optimized atomic copy\n");
132    o->ivar = nil;
133    TestRootRetain = 0;
134    TestRootCopyWithZone = 0;
135    TestRootMutableCopyWithZone = 0;
136    objc_setProperty_atomic_copy(o, _cmd, value, offset);
137    testassert(TestRootRetain == 0);
138    testassert(TestRootCopyWithZone == 1);
139    testassert(TestRootMutableCopyWithZone == 0);
140    testassert(o->ivar  &&  o->ivar != value);
141
142    succeed(__FILE__);
143}
144