wcc: converge let-IDENT memcpy, IDENT-assign recv, nested struct call-recv onto structabisize
Three more wwstage cgen sites still used unrounded structnaturalsize where cstage rounds via lu->size — pre-existing gate-blind cs!=ww latents the #169b reviewer surfaced: cgenstmt N_LET struct-IDENT memcpy (let p2: T = p1; twin cgen.c:7869), cgenexpr N_ASSIGN N_IDENT-lhs register RECV (s = mk(); twin cgen.c:4700-4737), and cgenutil's nested struct N_CALL recv inside cgstructlitfill (twin cgen.c:2121). Converge all three onto structabisize, completing the same-class closure started by #169 and continued by #169b. Also corrected the inline comment at cgenutil.ww:3273-3286 that wrongly claimed fl->type->size was natural (check.c:760 sets ABI). sretretsize at cgenutil.ww:1301 is gate-equivalent natural and is left alone. Probe 698 +3 rows (one per converged site) with cs==ww .s byte-cmp and a pre-fix-rebuild discriminator. 990-997 byte-id hold.
This commit is contained in:
@@ -242,6 +242,52 @@ static const struct row rows[] = {
|
||||
" return z.a + z.b + z.c;\n"
|
||||
"};\n",
|
||||
0 },
|
||||
/* `let p2: T = p1;` ident memcpy. struct{i64,i32} natural 12,
|
||||
* maxalign 8 → cstage N_LET sets sz = lu->size = 16 (cgen.c:7533,
|
||||
* struct-IDENT branch :7869) and emits MOVQ+MOVQ for the per-qword
|
||||
* copy. Pre-fix wwstage sized the run on structnaturalsize (12) →
|
||||
* MOVQ+MOVL. The byte-id catches the 4B widen; both stages
|
||||
* round-trip the value correctly because the high 4B of the rhs
|
||||
* slot were zero-init'd by the source let. */
|
||||
{ "let_ident_memcpy_pair_i64_i32",
|
||||
"type pt = struct { a: i64, b: i32 };\n"
|
||||
"fn main() i32 = {\n"
|
||||
" let p1: pt = pt { a = 7i64, b = 9i32 };\n"
|
||||
" let p2: pt = p1;\n"
|
||||
" return p2.b - 9;\n"
|
||||
"};\n",
|
||||
0 },
|
||||
/* `s = mk();` ident-lhs register RECV (sibling of dot_recv_call_*).
|
||||
* struct{i64,i32} natural 12, maxalign 8 → cstage N_ASSIGN-IDENT
|
||||
* sets sz = lu->size = 16 (cgen.c:4704) and stores AX/DX with
|
||||
* MOVQ+MOVQ. Pre-fix wwstage used structnaturalsize (12) →
|
||||
* MOVQ+MOVL. byte-id discriminator regardless of value readback. */
|
||||
{ "assign_ident_call_recv_pair_i64_i32",
|
||||
"type pt = struct { a: i64, b: i32 };\n"
|
||||
"fn mk() pt = { return pt { a = 7i64, b = 9i32 }; };\n"
|
||||
"fn main() i32 = {\n"
|
||||
" let s: pt = pt { a = 0i64, b = 0i32 };\n"
|
||||
" s = mk();\n"
|
||||
" return s.b - 9;\n"
|
||||
"};\n",
|
||||
0 },
|
||||
/* Nested struct N_CALL inside a structlit field: the outer literal
|
||||
* has field `v` whose type is struct{i64,i32}; the value is mk().
|
||||
* cstage's cg_structlit_fill reads fl->type->size at the nested-
|
||||
* call branch (cgen.c:2121) — per check.c:760 that's the maxalign-
|
||||
* rounded ABI extent (16). Pre-fix wwstage cgstructlitfill used
|
||||
* structnaturalsize (12) → MOVQ+MOVL where cstage emits MOVQ+MOVQ.
|
||||
* mk returns via a structlit so the producer side stays out of the
|
||||
* comparison; only the nested-call-recv ladder shifts. */
|
||||
{ "structlit_nested_call_recv_pair_i64_i32",
|
||||
"type pt = struct { a: i64, b: i32 };\n"
|
||||
"type box = struct { v: pt };\n"
|
||||
"fn mk() pt = { return pt { a = 7i64, b = 9i32 }; };\n"
|
||||
"fn main() i32 = {\n"
|
||||
" let b: box = box { v = mk() };\n"
|
||||
" return b.v.b - 9;\n"
|
||||
"};\n",
|
||||
0 },
|
||||
};
|
||||
|
||||
static int
|
||||
|
||||
Reference in New Issue
Block a user