kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

6_5_15_06_cond_struct_qualifier_mismatch.c (1522B)


      1 /* ยง6.5.15: when both operands of a conditional operator are structures, the
      2  * result has their common, unqualified structure type. The arms may differ in
      3  * qualification โ€” e.g. a `const` struct lvalue reached through a `const T*`
      4  * (`*cp`) versus a plain struct subobject (`s->n.f`).
      5  *
      6  * Regression: the parser reconciled the two arms with c_cg_convert, which โ€”
      7  * having no aggregate case โ€” fell into the scalar bitcast path and pushed the
      8  * struct as a value. The CG rejects that ("aggregate must be a place, not a
      9  * value"); on aarch64 it instead surfaced as "scalar too large". The trigger
     10  * is exactly src/dbg/symbolic.c's `start = top ? *top : s->stop.regs`. */
     11 typedef struct {
     12   int a, b;
     13 } P;
     14 struct N {
     15   P f;
     16 };
     17 struct S {
     18   struct N n;
     19 };
     20 
     21 /* const-deref arm vs nested-member arm (the symbolic.c shape). */
     22 static int pick(const P* cp, struct S* s, int useptr) {
     23   P r = useptr ? *cp : s->n.f;
     24   return r.a * 10 + r.b;
     25 }
     26 
     27 /* const-deref arm vs non-const-deref arm: same qualifier mismatch, both arms
     28  * materialized. */
     29 static int pick2(const P* cp, P* np, int useconst) {
     30   P r = useconst ? *cp : *np;
     31   return r.a * 100 + r.b;
     32 }
     33 
     34 int test_main(void) {
     35   P p = {3, 4};
     36   P q = {7, 8};
     37   struct S s = {{{5, 6}}};
     38   int viaptr = pick(&p, &s, 1); /* *cp    -> 34 */
     39   int viamem = pick(&p, &s, 0); /* s->n.f -> 56 */
     40   int c = pick2(&p, &q, 1);     /* *cp    -> 304 */
     41   int n = pick2(&p, &q, 0);     /* *np    -> 708 */
     42   return (viaptr == 34 && viamem == 56 && c == 304 && n == 708) ? 0 : 1;
     43 }