wcc/check: #24 reject composite-element tuple (array/struct/tuple), declared+inferred, both stages

A tuple whose element chases to TY_ARRAY/STRUCT/TUPLE (>8B) silently
miscompiled both stages: t.0[i] read segfaulted and construction dropped
the payload into the 8B slot. Reject the type at resolution (DISP-B);
faithful inline layout deferred to #60. cstage resolve_type N_TTUPLE
(declared) + N_TUPLE expr (inferred literal, was a cstage-only silent
miscompile + cs!=ww asymmetry); wwstage tinfofornode covers both.
test/wcc/832 + 941 migrated.
This commit is contained in:
2026-06-09 17:29:11 +09:00
parent f1cd0a3555
commit 785fe342fa
6 changed files with 144 additions and 33 deletions

View File

@@ -725,6 +725,18 @@ resolve_type(Checker *c, Node *n)
* packed-tuple miscompile family (#32/#33/#48). */
if (tp->type) {
Type *eu = type_chase_named(tp->type);
/* #24: a composite element (array/struct/nested
* tuple >8B) cannot ride the 8B cursor slot — the
* #60 layout drops it on construction and segvs on
* t.N[i] read. Reject until #60/DISP-A inlines it.
* Hare allows it (harec type_store.c anon-struct). */
if (eu && (eu->kind == TY_ARRAY
|| eu->kind == TY_STRUCT
|| eu->kind == TY_TUPLE))
err(c, n->pos, "tuple element must be a "
"scalar, str, slice, or tagged-union "
"(composite element deferred to task "
"#60)");
if (eu && (eu->kind == TY_STR
|| eu->kind == TY_SLICE
|| eu->kind == TY_TAGGED))
@@ -2182,6 +2194,20 @@ cexpr(Checker *c, Node *n)
Type *ed = type_default(tp->type);
if (ed && ed->align > al) al = ed->align;
Type *eu = type_chase_named(ed);
/* #24: an INFERRED composite element (array/struct/
* nested tuple >8B) drops on construction + segvs on
* the t.N read, exactly as the explicit N_TTUPLE twin
* (resolve_type) — wwstage's tinfofornode choke-point
* catches declared AND inferred, so cstage must reject
* the inferred literal here too (rule-10 symmetry).
* Reject until #60/DISP-A inlines it. */
if (eu && (eu->kind == TY_ARRAY
|| eu->kind == TY_STRUCT
|| eu->kind == TY_TUPLE))
err(c, n->pos, "tuple element must be a "
"scalar, str, slice, or tagged-union "
"(composite element deferred to task "
"#60)");
if (eu && (eu->kind == TY_STR || eu->kind == TY_SLICE
|| eu->kind == TY_TAGGED))
sz += (eu->size + 7) & ~(u64)7;