1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright (c) 2019, Joyent, Inc.
14 */
15
16 #include <sys/types.h>
17 #include <complex.h>
18
19 /*
20 * Test various structure and union constructs, including various things that
21 * have caused regressions in the past.
22 */
23
24 /*
25 * Basic, simple struct.
26 */
27 struct foo {
28 int a;
29 float b;
30 const char *c;
31 };
32
33 struct foo foo;
34
35 /*
36 * Self-referential structs
37 */
38 struct node {
39 struct node *prev;
40 struct node *next;
41 };
42
43 typedef struct nlist {
44 size_t size;
45 size_t off;
46 struct node head;
47 } nlist_t;
48
49 nlist_t head;
50
51 /*
52 * Struct that has a forward declaration.
53 */
54 typedef struct forward forward_t;
55 struct forward {
56 void *past;
57 void *present;
58 void *future;
59 };
60
61 const forward_t forward;
62
63 /*
64 * Here, we have a pair of structures that basically round up to different
65 * sizes. As in, the size of the structure is somewhat compiler dependent.
66 */
67 struct round_up {
68 uint8_t triforce;
69 uint32_t link;
70 uint8_t zelda;
71 uint8_t ganon;
72 };
73
74 #pragma pack(1)
75 struct fixed_up {
76 uint8_t triforce;
77 uint32_t link;
78 uint8_t zelda;
79 uint8_t ganon;
80 };
81 #pragma pack()
82
83 struct round_up oot;
84 struct fixed_up botw;
85
86 /*
87 * Various GNU and c99 style arrays
88 */
89 enum material {
90 COPPER,
91 IRON,
92 STEEL,
93 ADAMANTIUM,
94 MYTHRIL,
95 ORIHALCUM
96 };
97
98 struct component {
99 enum material m;
100 uint64_t grade;
101 uint64_t count;
102 const char *locations[4];
103 };
104
105 struct mysterious_barrel {
106 const char *name;
107 size_t capacity;
108 struct component optional[];
109 };
110
111 struct dusk_barrel {
112 const char *name;
113 size_t opacity;
114 struct component optional[0];
115 };
116
117 struct mysterious_barrel sophie;
118 struct dusk_barrel ayesha;
119
120 /*
121 * Various bitfield forms.
122 */
123
124 /*
125 * Variant of the Intel system_desc.
126 */
127 struct stats {
128 uint64_t hp:16;
129 uint64_t mp:16;
130 uint64_t str:8;
131 uint64_t dex:4;
132 uint64_t con:1;
133 uint64_t inte:2;
134 uint64_t wis:1;
135 uint64_t cha:4;
136 uint64_t sanity:1;
137 uint64_t attack:2;
138 uint64_t mattack:1;
139 uint64_t defense:8;
140 uint64_t mdefense:32;
141 uint64_t evasion:8;
142 uint64_t crit:5;
143 uint64_t luck:19;
144 };
145
146 struct stats stats;
147
148 /*
149 * More odd length structures due to bitfields
150 */
151 struct fellowship {
152 uint16_t frodo:1;
153 uint16_t sam:1;
154 uint16_t merry:1;
155 uint16_t pippin:1;
156 uint16_t aragorn:1;
157 uint16_t boromir:1;
158 uint16_t legolas:1;
159 uint16_t gimli:1;
160 uint16_t gandalf:1;
161 };
162
163 struct fellowship ring;
164
165 struct rings {
166 uint32_t elves:3;
167 uint32_t dwarves:7;
168 uint32_t men:9;
169 uint8_t one;
170 uint8_t silmarils[3];
171 };
172
173 struct rings rings;
174
175 /*
176 * Regression, we didn't handle receiving a negative offset from DWARF with
177 * this.
178 */
179 #pragma pack(1)
180 struct csts {
181 unsigned int rdy:7;
182 unsigned int csts:32;
183 };
184
185 struct csts nvme;
186 #pragma pack()
187
188 /*
189 * Onto unions
190 */
191 union jrpg {
192 int ff;
193 double atelier[4];
194 const char *tales;
195 int (*chrono)(void);
196 struct rings xeno;
197 };
198
199 union jrpg games;
200
201 #pragma pack(1)
202 struct android {
203 uint32_t _2b:16;
204 uint32_t _9s:16;
205 };
206
207 union nier {
208 uint32_t automata;
209 struct android android;
210 };
211 #pragma pack()
212
213 union nier nier;
214
215 union kh {
216 int sora:3;
217 char riku:7;
218 double kairi;
219 complex double namine;
220 };
221
222 union kh kh;
223
224 /*
225 * Anonymous union in a struct, GNU extension / C11
226 */
227
228 struct trigger {
229 uint8_t chrono;
230 uint8_t cross;
231 union {
232 void *lavos;
233 int *crono;
234 uint64_t schala[3];
235 };
236 };
237
238 struct trigger ct;
239
240 /*
241 * This is an array/union combo that failed conversion previously. Because it is
242 * static, we need to have a dummy function to make sure that clang doesn't
243 * optimize it away. Hopefully even with optimizations, this'll still be kept
244 * even though it's a constant.
245 */
246 static const union regress {
247 unsigned int i[3];
248 long double e;
249 } regress[9];
250
251 unsigned int
get_regress(void)252 get_regress(void)
253 {
254 return (regress[0].i[2]);
255 }
256