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 252 get_regress(void) 253 { 254 return (regress[0].i[2]); 255 } 256