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.
 242  */
 243 static const union regress {
 244         unsigned int i[3];
 245         long double e;
 246 } regress[9];