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.
61 KiB
61 KiB