wcc/cgen: S1 loud-stop subset-cast tagged widen in let+return (wwstage align to cstage #35)
A widening sub-union cast (return/let `v: inner` into a union whose member is the nested `inner`) skipped the nested widen arm and emitted tag=0 (a 2nd-variant value returned the wrong payload). cstage loud-stops #35; wwstage now matches: cgwidentaggedstorebp louds on the subset cast, and cgreturn routes genuine-widening tagged returns (rhs TY_TAGGED, ru1!=fu1) through the widener choke-point so the same loud fires. Same-type returns stay on the proven passthrough. Faithful inner-tag->outer-index remap deferred. test/wcc/835 S1 row.
This commit is contained in:
@@ -1037,6 +1037,29 @@ fn cgreturn(c: *cgen, n: *node) void = {
|
||||
if (taggedmemread(c, rhs)) {
|
||||
needswiden = true;
|
||||
};
|
||||
// S1/#35: a GENUINE-WIDENING tagged source
|
||||
// (stamped type_ TY_TAGGED and != fnret;
|
||||
// exact-type rides forwardtagged/plain above)
|
||||
// routes through the widener — tag remap for
|
||||
// ident/call (#218), #35 widen-subset loud for
|
||||
// cast/dot. Mirrors cstage cgreturn istagged→
|
||||
// cg_widen_tagged_store (cmd/w6c/cgen.c:13008-
|
||||
// 13011 → :2721). The ru1 != fu1 exclusion keeps
|
||||
// EXACT-type tagged casts on cstage's passthrough
|
||||
// (forwardtagged's own ru==fu equality) so byte-id
|
||||
// holds.
|
||||
let ru1: *tinfo = rhs.type_: *tinfo;
|
||||
ru1 = tichase(ru1);
|
||||
let fu1: *tinfo = nil;
|
||||
if (c.fnret != nil) {
|
||||
fu1 = c.fnret.type_: *tinfo;
|
||||
fu1 = tichase(fu1);
|
||||
};
|
||||
if (ru1 != nil && fu1 != nil) {
|
||||
if (ru1.kind == tykind.TY_TAGGED && ru1 != fu1) {
|
||||
needswiden = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
if (needswiden) {
|
||||
|
||||
Reference in New Issue
Block a user