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 * Copyright 2025 Oxide Computer Company 15 */ 16 17 #include <sys/types.h> 18 #include <complex.h> 19 20 /* 21 * Test various structure and union constructs, including various things that 22 * have caused regressions in the past. 23 */ 24 25 /* 26 * Basic, simple struct. 27 */ 28 struct foo { 29 int a; 30 float b; 31 const char *c; 32 }; 33 34 struct foo foo; 35 36 /* 37 * Self-referential structs 38 */ 39 struct node { 40 struct node *prev; 41 struct node *next; 42 }; 43 44 typedef struct nlist { 45 size_t size; 46 size_t off; 47 struct node head; 48 } nlist_t; 49 50 nlist_t head; 51 52 /* 53 * Struct that has a forward declaration. 54 */ 55 typedef struct forward forward_t; 56 struct forward { 57 void *past; 58 void *present; 59 void *future; 60 }; 61 62 const forward_t forward; 63 64 /* 65 * Here, we have a pair of structures that basically round up to different 66 * sizes. As in, the size of the structure is somewhat compiler dependent. 67 */ 68 struct round_up { 69 uint8_t triforce; 70 uint32_t link; 71 uint8_t zelda; 72 uint8_t ganon; 73 }; 74 75 #pragma pack(1) 76 struct fixed_up { 77 uint8_t triforce; 78 uint32_t link; 79 uint8_t zelda; 80 uint8_t ganon; 81 }; 82 #pragma pack() 83 84 struct round_up oot; 85 struct fixed_up botw; 86 87 /* 88 * Various GNU and c99 style arrays 89 */ 90 enum material { 91 COPPER, 92 IRON, 93 STEEL, 94 ADAMANTIUM, 95 MYTHRIL, 96 ORIHALCUM 97 }; 98 99 struct component { 100 enum material m; 101 uint64_t grade; 102 uint64_t count; 103 const char *locations[4]; 104 }; 105 106 struct mysterious_barrel { 107 const char *name; 108 size_t capacity; 109 struct component optional[]; 110 }; 111 112 struct dusk_barrel { 113 const char *name; 114 size_t opacity; 115 struct component optional[0]; 116 }; 117 118 struct mysterious_barrel sophie; 119 struct dusk_barrel ayesha; 120 121 /* 122 * Various bitfield forms. 123 */ 124 125 /* 126 * Variant of the Intel system_desc. 127 */ 128 struct stats { 129 uint64_t hp:16; 130 uint64_t mp:16; 131 uint64_t str:8; 132 uint64_t dex:4; 133 uint64_t con:1; 134 uint64_t inte:2; 135 uint64_t wis:1; 136 uint64_t cha:4; 137 uint64_t sanity:1; 138 uint64_t attack:2; 139 uint64_t mattack:1; 140 uint64_t defense:8; 141 uint64_t mdefense:32; 142 uint64_t evasion:8; 143 uint64_t crit:5; 144 uint64_t luck:19; 145 }; 146 147 struct stats stats; 148 149 /* 150 * More odd length structures due to bitfields 151 */ 152 struct fellowship { 153 uint16_t frodo:1; 154 uint16_t sam:1; 155 uint16_t merry:1; 156 uint16_t pippin:1; 157 uint16_t aragorn:1; 158 uint16_t boromir:1; 159 uint16_t legolas:1; 160 uint16_t gimli:1; 161 uint16_t gandalf:1; 162 }; 163 164 struct fellowship ring; 165 166 struct rings { 167 uint32_t elves:3; 168 uint32_t dwarves:7; 169 uint32_t men:9; 170 uint8_t one; 171 uint8_t silmarils[3]; 172 }; 173 174 struct rings rings; 175 176 /* 177 * Regression, we didn't handle receiving a negative offset from DWARF with 178 * this. 179 */ 180 #pragma pack(1) 181 struct csts { 182 unsigned int rdy:7; 183 unsigned int csts:32; 184 }; 185 186 struct csts nvme; 187 #pragma pack() 188 189 /* 190 * Onto unions 191 */ 192 union jrpg { 193 int ff; 194 double atelier[4]; 195 const char *tales; 196 int (*chrono)(void); 197 struct rings xeno; 198 }; 199 200 union jrpg games; 201 202 #pragma pack(1) 203 struct android { 204 uint32_t _2b:16; 205 uint32_t _9s:16; 206 }; 207 208 union nier { 209 uint32_t automata; 210 struct android android; 211 }; 212 #pragma pack() 213 214 union nier nier; 215 216 union kh { 217 int sora:3; 218 char riku:7; 219 double kairi; 220 complex double namine; 221 }; 222 223 union kh kh; 224 225 /* 226 * Anonymous union in a struct, GNU extension / C11 227 */ 228 229 struct trigger { 230 uint8_t chrono; 231 uint8_t cross; 232 union { 233 void *lavos; 234 int *crono; 235 uint64_t schala[3]; 236 }; 237 }; 238 239 struct trigger ct; 240 241 /* 242 * This is an array/union combo that failed conversion previously. Because it is 243 * static, we need to have a dummy function to make sure that clang doesn't 244 * optimize it away. Hopefully even with optimizations, this'll still be kept 245 * even though it's a constant. 246 */ 247 static const union regress { 248 unsigned int i[3]; 249 long double e; 250 } regress[9]; 251 252 unsigned int 253 get_regress(void) 254 { 255 return (regress[0].i[2]); 256 } 257 258 /* 259 * Now we have a series of different anonymous unions and structures. 260 */ 261 struct anon_basic { 262 int a; 263 union { 264 int b; 265 double c; 266 const char *d; 267 }; 268 struct { 269 int e; 270 const char *f; 271 unsigned int g[10]; 272 }; 273 }; 274 275 struct anon_basic anon_basic; 276 277 struct nested { 278 int a; 279 union { 280 int b; 281 struct { 282 int c; 283 int d; 284 int e; 285 union { 286 int g; 287 struct { 288 int h; 289 }; 290 }; 291 struct { 292 int i; 293 struct { 294 int j; 295 union { 296 int k; 297 struct { 298 int l; 299 int m; 300 }; 301 union { 302 int n; 303 struct { 304 int o; 305 int p; 306 }; 307 }; 308 }; 309 }; 310 }; 311 }; 312 }; 313 }; 314 315 struct nested nested; 316