336-struct-assign-ternary.c (1660B)
1 /* Struct = ternary, mirroring the shape tcc.flat.c expr_cond uses 2 * pervasively (CType locals + else-if chain). cc.scm has to lower 3 * each `type = bt1 == 6 ? type1 : type2;` as a struct copy whose 4 * size matches the struct (16 bytes here, including alignment pad 5 * for the void* member). Until this works, cc.scm-compiled 6 * tcc-boot2 self-corrupts when handed input that exercises that 7 * exact path in its embedded codegen. 8 */ 9 10 struct CType { int t; void *ref; }; 11 12 int main(void) 13 { 14 int dummy_a, dummy_b; 15 struct CType type1; type1.t = 6; type1.ref = &dummy_a; 16 struct CType type2; type2.t = 7; type2.ref = &dummy_b; 17 struct CType type; 18 19 int bt1 = 6, bt2 = 0; 20 if (bt1 == 6 || bt2 == 6) { 21 type = bt1 == 6 ? type1 : type2; 22 } else if (bt1 == 7 || bt2 == 7) { 23 type = bt1 == 7 ? type1 : type2; 24 } else { 25 type.t = -1; 26 type.ref = (void *)0; 27 } 28 if (type.t != 6) return 1; 29 if (type.ref != &dummy_a) return 2; 30 31 bt1 = 0; bt2 = 6; 32 if (bt1 == 6 || bt2 == 6) { 33 type = bt1 == 6 ? type1 : type2; 34 } else if (bt1 == 7 || bt2 == 7) { 35 type = bt1 == 7 ? type1 : type2; 36 } else { 37 type.t = -1; 38 type.ref = (void *)0; 39 } 40 if (type.t != 7) return 11; 41 if (type.ref != &dummy_b) return 12; 42 43 bt1 = 7; bt2 = 0; 44 if (bt1 == 6 || bt2 == 6) { 45 type = bt1 == 6 ? type1 : type2; 46 } else if (bt1 == 7 || bt2 == 7) { 47 type = bt1 == 7 ? type1 : type2; 48 } else { 49 type.t = -1; 50 type.ref = (void *)0; 51 } 52 if (type.t != 6) return 21; 53 if (type.ref != &dummy_a) return 22; 54 55 return 0; 56 }