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:
2026-06-09 17:32:06 +09:00
parent 64606de8af
commit 7e19d282f4
5 changed files with 164 additions and 1 deletions

View File

@@ -20350,6 +20350,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s
// NAMED tinfo (check.ww:1160-1173) so typeeq hits
// the a==b fast path.
let castisdst: bool = false;
let castsubset: bool = false;
let castrhs: *node = src.rhs;
if (castrhs != nil) {
let castt: *tinfo = castrhs.type_: *tinfo;
@@ -20361,10 +20362,30 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s
} else { if (castu.kind == tykind.TY_TAGGED) {
if (typeeq(castt, dst)) {
castisdst = true;
} else {
castsubset = true;
};
}; };
};
};
// S1/#35 (rule 7): a widen-SUBSET cast — the cast target
// is a TAGGED union that is NOT dst (castu tagged &&
// !typeeq(castt, dst)). The inner-variant tag is never
// remapped to dst's index, so the scalar arm below would
// emit tag=0: a SILENT mis-tag on any 2nd-variant value
// (census S1: `return true: inner`, inner=(int|bool) into
// (int|bool|str), ran the int arm not the bool arm). Loud-
// align to cstage cgen.c:2721-2723. The !inneristagged gate
// matches the src=inner collapse below — a tagged inner is
// handled by the #218 nested arm. Faithful remap (read inner
// tag, inner-idx→outer-idx) = the #23/#40 widen-subset
// feature, deferred post-CSP (needs the nominal variant-
// remap table).
if (castsubset && !inneristagged) {
let m35: str = "#35: tagged cast source shape unwired at the widen subset arm (rule 7)\n";
os.write(2, m35.ptr, m35.len: u64);
os.exit(1);
};
if (castisdst && !inneristagged) {
src = inner;
};
@@ -34980,6 +35001,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) {

View File

@@ -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) {

View File

@@ -3838,6 +3838,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s
// NAMED tinfo (check.ww:1160-1173) so typeeq hits
// the a==b fast path.
let castisdst: bool = false;
let castsubset: bool = false;
let castrhs: *node = src.rhs;
if (castrhs != nil) {
let castt: *tinfo = castrhs.type_: *tinfo;
@@ -3849,10 +3850,30 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s
} else { if (castu.kind == tykind.TY_TAGGED) {
if (typeeq(castt, dst)) {
castisdst = true;
} else {
castsubset = true;
};
}; };
};
};
// S1/#35 (rule 7): a widen-SUBSET cast — the cast target
// is a TAGGED union that is NOT dst (castu tagged &&
// !typeeq(castt, dst)). The inner-variant tag is never
// remapped to dst's index, so the scalar arm below would
// emit tag=0: a SILENT mis-tag on any 2nd-variant value
// (census S1: `return true: inner`, inner=(int|bool) into
// (int|bool|str), ran the int arm not the bool arm). Loud-
// align to cstage cgen.c:2721-2723. The !inneristagged gate
// matches the src=inner collapse below — a tagged inner is
// handled by the #218 nested arm. Faithful remap (read inner
// tag, inner-idx→outer-idx) = the #23/#40 widen-subset
// feature, deferred post-CSP (needs the nominal variant-
// remap table).
if (castsubset && !inneristagged) {
let m35: str = "#35: tagged cast source shape unwired at the widen subset arm (rule 7)\n";
os.write(2, m35.ptr, m35.len: u64);
os.exit(1);
};
if (castisdst && !inneristagged) {
src = inner;
};

View File

@@ -20350,6 +20350,7 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s
// NAMED tinfo (check.ww:1160-1173) so typeeq hits
// the a==b fast path.
let castisdst: bool = false;
let castsubset: bool = false;
let castrhs: *node = src.rhs;
if (castrhs != nil) {
let castt: *tinfo = castrhs.type_: *tinfo;
@@ -20361,10 +20362,30 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s
} else { if (castu.kind == tykind.TY_TAGGED) {
if (typeeq(castt, dst)) {
castisdst = true;
} else {
castsubset = true;
};
}; };
};
};
// S1/#35 (rule 7): a widen-SUBSET cast — the cast target
// is a TAGGED union that is NOT dst (castu tagged &&
// !typeeq(castt, dst)). The inner-variant tag is never
// remapped to dst's index, so the scalar arm below would
// emit tag=0: a SILENT mis-tag on any 2nd-variant value
// (census S1: `return true: inner`, inner=(int|bool) into
// (int|bool|str), ran the int arm not the bool arm). Loud-
// align to cstage cgen.c:2721-2723. The !inneristagged gate
// matches the src=inner collapse below — a tagged inner is
// handled by the #218 nested arm. Faithful remap (read inner
// tag, inner-idx→outer-idx) = the #23/#40 widen-subset
// feature, deferred post-CSP (needs the nominal variant-
// remap table).
if (castsubset && !inneristagged) {
let m35: str = "#35: tagged cast source shape unwired at the widen subset arm (rule 7)\n";
os.write(2, m35.ptr, m35.len: u64);
os.exit(1);
};
if (castisdst && !inneristagged) {
src = inner;
};
@@ -34980,6 +35001,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) {