Files
ww/Makefile
Hojun-Cho f9f83faca7 wwstage: remap error tag on try-propagate across reordered unions (#173)
wwstage cgtryprop returned the operand union's RAW tag when propagating a
`c(s)?` error, while cstage (cmd/w6c/cgen.c:6161-6184) remaps it to the
enclosing return union's variant ordering. When the operand and return
unions differ in variant order, wwstage propagated the WRONG error variant
at runtime — gate-blind: byte-id (990-997) and cstage==wwstage asm both pass
because the bootstrap only ever tries same-order unions, while the
differing-order case is silently wrong.

Port cstage's remap loop into cgtryprop (iserror-only): for each error
variant whose return-union index differs, emit the CMPQ/JNE/MOVQ/JMP that
rewrites the tag in AX; the error payload words (DX/CX/R8) are untouched and
ride the RET. Mirror cstage's emission exactly — lazy tryprop_ret allocation
on the first remap, j==i skip, j<0 fallback, no dead label when empty,
identical label strings and operand order — so same-order emits zero extra
instructions (byte-id preserved) and differing-order is now byte-identical
cstage==wwstage.

Scope: error-variant remap only. wwstage's hardcoded success-tag=0 and
iserror-only error detection (vs cstage's cg_tagged_success_tag +
cg_variant_is_error legacy fallback) diverge for non-idx-0-success or
unmarked unions — also gate-blind, also latent — filed separately as #216.

test/wcc/925_tryprop_tag_remap_run: 5 rows (differing-order for both error
variants, success unwrap, same-order byte-id witness, and a multi-word !str
payload row asserting the payload bytes survive the remap), each with a
cstage==wwstage .s byte-id check.
2026-05-29 19:43:48 +09:00

61 KiB