15bb525f4SRobert Mustacchi /*
25bb525f4SRobert Mustacchi  * This file and its contents are supplied under the terms of the
35bb525f4SRobert Mustacchi  * Common Development and Distribution License ("CDDL"), version 1.0.
45bb525f4SRobert Mustacchi  * You may only use this file in accordance with the terms of version
55bb525f4SRobert Mustacchi  * 1.0 of the CDDL.
65bb525f4SRobert Mustacchi  *
75bb525f4SRobert Mustacchi  * A full copy of the text of the CDDL should have accompanied this
85bb525f4SRobert Mustacchi  * source.  A copy of the CDDL is also available via the Internet at
95bb525f4SRobert Mustacchi  * http://www.illumos.org/license/CDDL.
105bb525f4SRobert Mustacchi  */
115bb525f4SRobert Mustacchi 
125bb525f4SRobert Mustacchi /*
135bb525f4SRobert Mustacchi  * Copyright (c) 2019, Joyent, Inc.
145bb525f4SRobert Mustacchi  */
155bb525f4SRobert Mustacchi 
165bb525f4SRobert Mustacchi #include <sys/types.h>
175bb525f4SRobert Mustacchi #include <complex.h>
185bb525f4SRobert Mustacchi 
195bb525f4SRobert Mustacchi /*
205bb525f4SRobert Mustacchi  * Test various structure and union constructs, including various things that
215bb525f4SRobert Mustacchi  * have caused regressions in the past.
225bb525f4SRobert Mustacchi  */
235bb525f4SRobert Mustacchi 
245bb525f4SRobert Mustacchi /*
255bb525f4SRobert Mustacchi  * Basic, simple struct.
265bb525f4SRobert Mustacchi  */
275bb525f4SRobert Mustacchi struct foo {
285bb525f4SRobert Mustacchi 	int a;
295bb525f4SRobert Mustacchi 	float b;
305bb525f4SRobert Mustacchi 	const char *c;
315bb525f4SRobert Mustacchi };
325bb525f4SRobert Mustacchi 
335bb525f4SRobert Mustacchi struct foo foo;
345bb525f4SRobert Mustacchi 
355bb525f4SRobert Mustacchi /*
365bb525f4SRobert Mustacchi  * Self-referential structs
375bb525f4SRobert Mustacchi  */
385bb525f4SRobert Mustacchi struct node {
395bb525f4SRobert Mustacchi 	struct node *prev;
405bb525f4SRobert Mustacchi 	struct node *next;
415bb525f4SRobert Mustacchi };
425bb525f4SRobert Mustacchi 
435bb525f4SRobert Mustacchi typedef struct nlist {
445bb525f4SRobert Mustacchi 	size_t size;
455bb525f4SRobert Mustacchi 	size_t off;
465bb525f4SRobert Mustacchi 	struct node head;
475bb525f4SRobert Mustacchi } nlist_t;
485bb525f4SRobert Mustacchi 
495bb525f4SRobert Mustacchi nlist_t head;
505bb525f4SRobert Mustacchi 
515bb525f4SRobert Mustacchi /*
525bb525f4SRobert Mustacchi  * Struct that has a forward declaration.
535bb525f4SRobert Mustacchi  */
545bb525f4SRobert Mustacchi typedef struct forward forward_t;
555bb525f4SRobert Mustacchi struct forward {
565bb525f4SRobert Mustacchi 	void *past;
575bb525f4SRobert Mustacchi 	void *present;
585bb525f4SRobert Mustacchi 	void *future;
595bb525f4SRobert Mustacchi };
605bb525f4SRobert Mustacchi 
615bb525f4SRobert Mustacchi const forward_t forward;
625bb525f4SRobert Mustacchi 
635bb525f4SRobert Mustacchi /*
645bb525f4SRobert Mustacchi  * Here, we have a pair of structures that basically round up to different
655bb525f4SRobert Mustacchi  * sizes. As in, the size of the structure is somewhat compiler dependent.
665bb525f4SRobert Mustacchi  */
675bb525f4SRobert Mustacchi struct round_up {
685bb525f4SRobert Mustacchi 	uint8_t triforce;
695bb525f4SRobert Mustacchi 	uint32_t link;
705bb525f4SRobert Mustacchi 	uint8_t zelda;
715bb525f4SRobert Mustacchi 	uint8_t ganon;
725bb525f4SRobert Mustacchi };
735bb525f4SRobert Mustacchi 
745bb525f4SRobert Mustacchi #pragma pack(1)
755bb525f4SRobert Mustacchi struct fixed_up {
765bb525f4SRobert Mustacchi 	uint8_t triforce;
775bb525f4SRobert Mustacchi 	uint32_t link;
785bb525f4SRobert Mustacchi 	uint8_t zelda;
795bb525f4SRobert Mustacchi 	uint8_t ganon;
805bb525f4SRobert Mustacchi };
815bb525f4SRobert Mustacchi #pragma pack()
825bb525f4SRobert Mustacchi 
835bb525f4SRobert Mustacchi struct round_up oot;
845bb525f4SRobert Mustacchi struct fixed_up botw;
855bb525f4SRobert Mustacchi 
865bb525f4SRobert Mustacchi /*
875bb525f4SRobert Mustacchi  * Various GNU and c99 style arrays
885bb525f4SRobert Mustacchi  */
895bb525f4SRobert Mustacchi enum material {
905bb525f4SRobert Mustacchi 	COPPER,
915bb525f4SRobert Mustacchi 	IRON,
925bb525f4SRobert Mustacchi 	STEEL,
935bb525f4SRobert Mustacchi 	ADAMANTIUM,
945bb525f4SRobert Mustacchi 	MYTHRIL,
955bb525f4SRobert Mustacchi 	ORIHALCUM
965bb525f4SRobert Mustacchi };
975bb525f4SRobert Mustacchi 
985bb525f4SRobert Mustacchi struct component {
995bb525f4SRobert Mustacchi 	enum material m;
1005bb525f4SRobert Mustacchi 	uint64_t grade;
1015bb525f4SRobert Mustacchi 	uint64_t count;
1025bb525f4SRobert Mustacchi 	const char *locations[4];
1035bb525f4SRobert Mustacchi };
1045bb525f4SRobert Mustacchi 
1055bb525f4SRobert Mustacchi struct mysterious_barrel {
1065bb525f4SRobert Mustacchi 	const char *name;
1075bb525f4SRobert Mustacchi 	size_t capacity;
1085bb525f4SRobert Mustacchi 	struct component optional[];
1095bb525f4SRobert Mustacchi };
1105bb525f4SRobert Mustacchi 
1115bb525f4SRobert Mustacchi struct dusk_barrel {
1125bb525f4SRobert Mustacchi 	const char *name;
1135bb525f4SRobert Mustacchi 	size_t opacity;
1145bb525f4SRobert Mustacchi 	struct component optional[0];
1155bb525f4SRobert Mustacchi };
1165bb525f4SRobert Mustacchi 
1175bb525f4SRobert Mustacchi struct mysterious_barrel sophie;
1185bb525f4SRobert Mustacchi struct dusk_barrel ayesha;
1195bb525f4SRobert Mustacchi 
1205bb525f4SRobert Mustacchi /*
1215bb525f4SRobert Mustacchi  * Various bitfield forms.
1225bb525f4SRobert Mustacchi  */
1235bb525f4SRobert Mustacchi 
1245bb525f4SRobert Mustacchi /*
1255bb525f4SRobert Mustacchi  * Variant of the Intel system_desc.
1265bb525f4SRobert Mustacchi  */
1275bb525f4SRobert Mustacchi struct stats {
1285bb525f4SRobert Mustacchi 	uint64_t hp:16;
1295bb525f4SRobert Mustacchi 	uint64_t mp:16;
1305bb525f4SRobert Mustacchi 	uint64_t str:8;
1315bb525f4SRobert Mustacchi 	uint64_t dex:4;
1325bb525f4SRobert Mustacchi 	uint64_t con:1;
1335bb525f4SRobert Mustacchi 	uint64_t inte:2;
1345bb525f4SRobert Mustacchi 	uint64_t wis:1;
1355bb525f4SRobert Mustacchi 	uint64_t cha:4;
1365bb525f4SRobert Mustacchi 	uint64_t sanity:1;
1375bb525f4SRobert Mustacchi 	uint64_t attack:2;
1385bb525f4SRobert Mustacchi 	uint64_t mattack:1;
1395bb525f4SRobert Mustacchi 	uint64_t defense:8;
1405bb525f4SRobert Mustacchi 	uint64_t mdefense:32;
1415bb525f4SRobert Mustacchi 	uint64_t evasion:8;
1425bb525f4SRobert Mustacchi 	uint64_t crit:5;
1435bb525f4SRobert Mustacchi 	uint64_t luck:19;
1445bb525f4SRobert Mustacchi };
1455bb525f4SRobert Mustacchi 
1465bb525f4SRobert Mustacchi struct stats stats;
1475bb525f4SRobert Mustacchi 
1485bb525f4SRobert Mustacchi /*
1495bb525f4SRobert Mustacchi  * More odd length structures due to bitfields
1505bb525f4SRobert Mustacchi  */
1515bb525f4SRobert Mustacchi struct fellowship {
1525bb525f4SRobert Mustacchi 	uint16_t frodo:1;
1535bb525f4SRobert Mustacchi 	uint16_t sam:1;
1545bb525f4SRobert Mustacchi 	uint16_t merry:1;
1555bb525f4SRobert Mustacchi 	uint16_t pippin:1;
1565bb525f4SRobert Mustacchi 	uint16_t aragorn:1;
1575bb525f4SRobert Mustacchi 	uint16_t boromir:1;
1585bb525f4SRobert Mustacchi 	uint16_t legolas:1;
1595bb525f4SRobert Mustacchi 	uint16_t gimli:1;
1605bb525f4SRobert Mustacchi 	uint16_t gandalf:1;
1615bb525f4SRobert Mustacchi };
1625bb525f4SRobert Mustacchi 
1635bb525f4SRobert Mustacchi struct fellowship ring;
1645bb525f4SRobert Mustacchi 
1655bb525f4SRobert Mustacchi struct rings {
1665bb525f4SRobert Mustacchi 	uint32_t elves:3;
1675bb525f4SRobert Mustacchi 	uint32_t dwarves:7;
1685bb525f4SRobert Mustacchi 	uint32_t men:9;
1695bb525f4SRobert Mustacchi 	uint8_t one;
1705bb525f4SRobert Mustacchi 	uint8_t silmarils[3];
1715bb525f4SRobert Mustacchi };
1725bb525f4SRobert Mustacchi 
1735bb525f4SRobert Mustacchi struct rings rings;
1745bb525f4SRobert Mustacchi 
1755bb525f4SRobert Mustacchi /*
1765bb525f4SRobert Mustacchi  * Regression, we didn't handle receiving a negative offset from DWARF with
1775bb525f4SRobert Mustacchi  * this.
1785bb525f4SRobert Mustacchi  */
1795bb525f4SRobert Mustacchi #pragma pack(1)
1805bb525f4SRobert Mustacchi struct csts {
1815bb525f4SRobert Mustacchi 	unsigned int rdy:7;
1825bb525f4SRobert Mustacchi 	unsigned int csts:32;
1835bb525f4SRobert Mustacchi };
1845bb525f4SRobert Mustacchi 
1855bb525f4SRobert Mustacchi struct csts nvme;
1865bb525f4SRobert Mustacchi #pragma pack()
1875bb525f4SRobert Mustacchi 
1885bb525f4SRobert Mustacchi /*
1895bb525f4SRobert Mustacchi  * Onto unions
1905bb525f4SRobert Mustacchi  */
1915bb525f4SRobert Mustacchi union jrpg {
1925bb525f4SRobert Mustacchi 	int ff;
1935bb525f4SRobert Mustacchi 	double atelier[4];
1945bb525f4SRobert Mustacchi 	const char *tales;
1955bb525f4SRobert Mustacchi 	int (*chrono)(void);
1965bb525f4SRobert Mustacchi 	struct rings xeno;
1975bb525f4SRobert Mustacchi };
1985bb525f4SRobert Mustacchi 
1995bb525f4SRobert Mustacchi union jrpg games;
2005bb525f4SRobert Mustacchi 
2015bb525f4SRobert Mustacchi #pragma pack(1)
2025bb525f4SRobert Mustacchi struct android {
2035bb525f4SRobert Mustacchi 	uint32_t _2b:16;
2045bb525f4SRobert Mustacchi 	uint32_t _9s:16;
2055bb525f4SRobert Mustacchi };
2065bb525f4SRobert Mustacchi 
2075bb525f4SRobert Mustacchi union nier {
2085bb525f4SRobert Mustacchi 	uint32_t automata;
2095bb525f4SRobert Mustacchi 	struct android android;
2105bb525f4SRobert Mustacchi };
2115bb525f4SRobert Mustacchi #pragma pack()
2125bb525f4SRobert Mustacchi 
2135bb525f4SRobert Mustacchi union nier nier;
2145bb525f4SRobert Mustacchi 
2155bb525f4SRobert Mustacchi union kh {
2165bb525f4SRobert Mustacchi 	int sora:3;
2175bb525f4SRobert Mustacchi 	char riku:7;
2185bb525f4SRobert Mustacchi 	double kairi;
2195bb525f4SRobert Mustacchi 	complex double namine;
2205bb525f4SRobert Mustacchi };
2215bb525f4SRobert Mustacchi 
2225bb525f4SRobert Mustacchi union kh kh;
2235bb525f4SRobert Mustacchi 
2245bb525f4SRobert Mustacchi /*
2255bb525f4SRobert Mustacchi  * Anonymous union in a struct, GNU extension / C11
2265bb525f4SRobert Mustacchi  */
2275bb525f4SRobert Mustacchi 
2285bb525f4SRobert Mustacchi struct trigger {
2295bb525f4SRobert Mustacchi 	uint8_t chrono;
2305bb525f4SRobert Mustacchi 	uint8_t cross;
2315bb525f4SRobert Mustacchi 	union {
2325bb525f4SRobert Mustacchi 		void *lavos;
2335bb525f4SRobert Mustacchi 		int *crono;
2345bb525f4SRobert Mustacchi 		uint64_t schala[3];
2355bb525f4SRobert Mustacchi 	};
2365bb525f4SRobert Mustacchi };
2375bb525f4SRobert Mustacchi 
2385bb525f4SRobert Mustacchi struct trigger ct;
2395bb525f4SRobert Mustacchi 
2405bb525f4SRobert Mustacchi /*
241*3cec9822SRobert Mustacchi  * This is an array/union combo that failed conversion previously. Because it is
242*3cec9822SRobert Mustacchi  * static, we need to have a dummy function to make sure that clang doesn't
243*3cec9822SRobert Mustacchi  * optimize it away. Hopefully even with optimizations, this'll still be kept
244*3cec9822SRobert Mustacchi  * even though it's a constant.
2455bb525f4SRobert Mustacchi  */
2465bb525f4SRobert Mustacchi static const union regress {
2475bb525f4SRobert Mustacchi 	unsigned int i[3];
2485bb525f4SRobert Mustacchi 	long double e;
2495bb525f4SRobert Mustacchi } regress[9];
250*3cec9822SRobert Mustacchi 
251*3cec9822SRobert Mustacchi unsigned int
get_regress(void)252*3cec9822SRobert Mustacchi get_regress(void)
253*3cec9822SRobert Mustacchi {
254*3cec9822SRobert Mustacchi 	return (regress[0].i[2]);
255*3cec9822SRobert Mustacchi }
256