modernc.org/ccgo/v3@v3.16.14/lib/testdata/bug/union4.c (about) 1 #include <stdbool.h> 2 #include <stdint.h> 3 4 typedef int Length, TSSymbol, TSStateId; 5 6 typedef struct { 7 bool is_inline : 1; 8 bool visible : 1; 9 bool named : 1; 10 bool extra : 1; 11 bool has_changes : 1; 12 bool is_missing : 1; 13 bool is_keyword : 1; 14 uint8_t symbol; 15 uint8_t padding_bytes; 16 uint8_t size_bytes; 17 uint8_t padding_columns; 18 uint8_t padding_rows : 4; 19 uint8_t lookahead_bytes : 4; 20 uint16_t parse_state; 21 } SubtreeInlineData; 22 23 typedef struct { 24 union { 25 char *long_data; 26 char short_data[24]; 27 }; 28 uint32_t length; 29 } ExternalScannerState; 30 31 typedef struct { 32 volatile uint32_t ref_count; 33 Length padding; 34 Length size; 35 uint32_t lookahead_bytes; 36 uint32_t error_cost; 37 uint32_t child_count; 38 TSSymbol symbol; 39 TSStateId parse_state; 40 41 bool visible : 1; 42 bool named : 1; 43 bool extra : 1; 44 bool fragile_left : 1; 45 bool fragile_right : 1; 46 bool has_changes : 1; 47 bool has_external_tokens : 1; 48 bool depends_on_column: 1; 49 bool is_missing : 1; 50 bool is_keyword : 1; 51 52 union { 53 // Non-terminal subtrees (`child_count > 0`) 54 struct { 55 uint32_t visible_child_count; 56 uint32_t named_child_count; 57 uint32_t node_count; 58 uint32_t repeat_depth; 59 int32_t dynamic_precedence; 60 uint16_t production_id; 61 struct { 62 TSSymbol symbol; 63 TSStateId parse_state; 64 } first_leaf; 65 }; 66 67 // External terminal subtrees (`child_count == 0 && has_external_tokens`) 68 ExternalScannerState external_scanner_state; 69 70 // Error terminal subtrees (`child_count == 0 && symbol == ts_builtin_sym_error`) 71 int32_t lookahead_char; 72 }; 73 } SubtreeHeapData; 74 75 typedef union { 76 SubtreeInlineData data; 77 const SubtreeHeapData *ptr; 78 } Subtree; 79 80 int main() { 81 Subtree external_token; 82 SubtreeHeapData hd; 83 external_token.ptr = &hd; 84 ExternalScannerState ss; 85 ss.length = 42; 86 hd.external_scanner_state = ss; 87 int i; 88 i = external_token.ptr 89 ->external_scanner_state.length; 90 if (i != 42) { 91 return __LINE__; 92 } 93 94 return 0; 95 }