]>
Commit | Line | Data |
---|---|---|
13ba007e A |
1 | /* |
2 | TEST_BUILD_OUTPUT | |
3 | .*ivar.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\](\n.* note: expanded from macro 'testassert')? | |
4 | .*ivar.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\](\n.* note: expanded from macro 'testassert')? | |
5 | .*ivar.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\](\n.* note: expanded from macro 'testassert')? | |
6 | .*ivar.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\](\n.* note: expanded from macro 'testassert')? | |
7 | .*ivar.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\] | |
8 | .*ivar.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\] | |
9 | .*ivar.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\](\n.* note: expanded from macro 'testassert')? | |
10 | .*ivar.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\](\n.* note: expanded from macro 'testassert')? | |
11 | .*ivar.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\](\n.* note: expanded from macro 'testassert')? | |
12 | .*ivar.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\](\n.* note: expanded from macro 'testassert')? | |
13 | .*ivar.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\](\n.* note: expanded from macro 'testassert')? | |
14 | .*ivar.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\](\n.* note: expanded from macro 'testassert')? | |
15 | END | |
16 | */ | |
17 | ||
18 | #include "test.h" | |
19 | #include "testroot.i" | |
20 | #include <stdint.h> | |
21 | #include <string.h> | |
22 | #include <objc/objc-runtime.h> | |
23 | ||
24 | @interface Super : TestRoot { | |
25 | @public | |
26 | char superIvar; | |
27 | } | |
28 | @end | |
29 | ||
30 | @interface Sub : Super { | |
31 | @public | |
32 | id subIvar; | |
33 | } | |
34 | @end | |
35 | ||
36 | @implementation Super @end | |
37 | @implementation Sub @end | |
38 | ||
39 | ||
40 | int main() | |
41 | { | |
42 | /* | |
43 | Runtime layout of Sub: | |
44 | [0] isa | |
45 | [1] superIvar | |
46 | [2] subIvar | |
47 | */ | |
48 | ||
49 | Ivar ivar; | |
50 | Sub *sub = [Sub new]; | |
51 | sub->subIvar = [Sub class]; | |
52 | testassert(((Class *)(__bridge void *)sub)[2] == [Sub class]); | |
53 | ||
54 | ivar = class_getInstanceVariable([Sub class], "subIvar"); | |
55 | testassert(ivar); | |
56 | testassert(2*sizeof(intptr_t) == (size_t)ivar_getOffset(ivar)); | |
57 | testassert(0 == strcmp(ivar_getName(ivar), "subIvar")); | |
58 | testassert(0 == strcmp(ivar_getTypeEncoding(ivar), "@")); | |
59 | ||
60 | ivar = class_getInstanceVariable([Super class], "superIvar"); | |
61 | testassert(ivar); | |
62 | testassert(sizeof(intptr_t) == (size_t)ivar_getOffset(ivar)); | |
63 | testassert(0 == strcmp(ivar_getName(ivar), "superIvar")); | |
64 | testassert(0 == strcmp(ivar_getTypeEncoding(ivar), "c")); | |
65 | testassert(ivar == class_getInstanceVariable([Sub class], "superIvar")); | |
66 | ||
67 | ivar = class_getInstanceVariable([Super class], "subIvar"); | |
68 | testassert(!ivar); | |
69 | ||
70 | ivar = class_getInstanceVariable(object_getClass([Sub class]), "subIvar"); | |
71 | testassert(!ivar); | |
72 | ||
73 | ivar = class_getInstanceVariable([Sub class], "subIvar"); | |
74 | object_setIvar(sub, ivar, sub); | |
75 | testassert(sub->subIvar == sub); | |
76 | testassert(sub == object_getIvar(sub, ivar)); | |
77 | ||
78 | testassert(NULL == class_getInstanceVariable(NULL, "foo")); | |
79 | testassert(NULL == class_getInstanceVariable([Sub class], NULL)); | |
80 | testassert(NULL == class_getInstanceVariable(NULL, NULL)); | |
81 | ||
82 | testassert(NULL == object_getIvar(sub, NULL)); | |
83 | testassert(NULL == object_getIvar(NULL, ivar)); | |
84 | testassert(NULL == object_getIvar(NULL, NULL)); | |
85 | ||
86 | object_setIvar(sub, NULL, NULL); | |
87 | object_setIvar(NULL, ivar, NULL); | |
88 | object_setIvar(NULL, NULL, NULL); | |
89 | ||
90 | #if !__has_feature(objc_arc) | |
91 | ||
92 | uintptr_t value; | |
93 | ||
94 | sub->subIvar = (id)10; | |
95 | value = 0; | |
96 | object_getInstanceVariable(sub, "subIvar", (void **)&value); | |
97 | testassert(value == 10); | |
98 | ||
99 | object_setInstanceVariable(sub, "subIvar", (id)11); | |
100 | testassert(sub->subIvar == (id)11); | |
101 | ||
102 | ivar = class_getInstanceVariable([Sub class], "subIvar"); | |
103 | testassert(ivar == object_getInstanceVariable(sub, "subIvar", NULL)); | |
104 | ||
105 | testassert(NULL == object_getInstanceVariable(sub, NULL, NULL)); | |
106 | testassert(NULL == object_getInstanceVariable(NULL, "foo", NULL)); | |
107 | testassert(NULL == object_getInstanceVariable(NULL, NULL, NULL)); | |
108 | value = 10; | |
109 | testassert(NULL == object_getInstanceVariable(sub, NULL, (void **)&value)); | |
110 | testassert(value == 0); | |
111 | value = 10; | |
112 | testassert(NULL == object_getInstanceVariable(NULL, "foo", (void **)&value)); | |
113 | testassert(value == 0); | |
114 | value = 10; | |
115 | testassert(NULL == object_getInstanceVariable(NULL, NULL, (void **)&value)); | |
116 | testassert(value == 0); | |
117 | ||
118 | testassert(NULL == object_setInstanceVariable(sub, NULL, NULL)); | |
119 | testassert(NULL == object_setInstanceVariable(NULL, "foo", NULL)); | |
120 | testassert(NULL == object_setInstanceVariable(NULL, NULL, NULL)); | |
121 | #else | |
122 | // provoke the same nullability warnings as the real test | |
123 | objc_getClass(nil); | |
124 | objc_getClass(nil); | |
125 | objc_getClass(nil); | |
126 | objc_getClass(nil); | |
127 | objc_getClass(nil); | |
128 | objc_getClass(nil); | |
129 | #endif | |
130 | ||
131 | succeed(__FILE__); | |
132 | return 0; | |
133 | } |