wcc/ww: paramfieldsize sizes a tagged-union destructure binding
A tagged for-range destructure binding took the 8-byte default (paramfieldsize had no tagged arm), skipping the full-extent copy — the wwstage twin of the just-closed cstage destructure family. Read the stamped tinfo size through the type table (twin of the slice arm; cstage reads tp->type->size). Task #53.
This commit is contained in:
@@ -39221,6 +39221,22 @@ fn paramfieldsize(t: *node) i32 = {
|
||||
// tyslicesize() is the slice-header SSoT (rule-13); cstage reads the
|
||||
// same width via tp->type->size (cmd/w6c/cgen.c N_FORRANGE).
|
||||
if (k == nkind.N_TSLICE) { return tyslicesize(): i32; };
|
||||
// #53: a tagged-union tuple-field carries its full box (tag + widest
|
||||
// payload, slot-padded), NOT the 8B scalar default — a for-range
|
||||
// destructure binding sized 8 loaded only the tag word (cs=56/ww=9, the
|
||||
// cat-A repro). The box width is variant-dependent, so read it from the
|
||||
// checker-stamped tinfo (rule-13): cstage's tp->type->size reads the same
|
||||
// resolved width. The stamp already collapsed any alias, so this also
|
||||
// covers an N_TNAME field naming a tagged union (paramfieldsize's no-`c`
|
||||
// structural contract can't aliaslookup-chase the node). Mirrors the
|
||||
// N_TSLICE arm's type-table SSoT.
|
||||
let tgi: *tinfo = t.type_: *tinfo;
|
||||
if (tgi != nil) {
|
||||
tgi = tichase(tgi);
|
||||
if (tgi != nil && tgi.kind == tykind.TY_TAGGED) {
|
||||
return tgi.size: i32;
|
||||
};
|
||||
};
|
||||
// #43 (F7-c4): a nested tuple field sizes as the sum of its element
|
||||
// SLOTS — each element floored UP to one 8B eightbyte (str/slice keep
|
||||
// their 24B header), per the tuple-slot ruling and tupeslot's
|
||||
|
||||
@@ -3669,6 +3669,22 @@ fn paramfieldsize(t: *node) i32 = {
|
||||
// tyslicesize() is the slice-header SSoT (rule-13); cstage reads the
|
||||
// same width via tp->type->size (cmd/w6c/cgen.c N_FORRANGE).
|
||||
if (k == nkind.N_TSLICE) { return tyslicesize(): i32; };
|
||||
// #53: a tagged-union tuple-field carries its full box (tag + widest
|
||||
// payload, slot-padded), NOT the 8B scalar default — a for-range
|
||||
// destructure binding sized 8 loaded only the tag word (cs=56/ww=9, the
|
||||
// cat-A repro). The box width is variant-dependent, so read it from the
|
||||
// checker-stamped tinfo (rule-13): cstage's tp->type->size reads the same
|
||||
// resolved width. The stamp already collapsed any alias, so this also
|
||||
// covers an N_TNAME field naming a tagged union (paramfieldsize's no-`c`
|
||||
// structural contract can't aliaslookup-chase the node). Mirrors the
|
||||
// N_TSLICE arm's type-table SSoT.
|
||||
let tgi: *tinfo = t.type_: *tinfo;
|
||||
if (tgi != nil) {
|
||||
tgi = tichase(tgi);
|
||||
if (tgi != nil && tgi.kind == tykind.TY_TAGGED) {
|
||||
return tgi.size: i32;
|
||||
};
|
||||
};
|
||||
// #43 (F7-c4): a nested tuple field sizes as the sum of its element
|
||||
// SLOTS — each element floored UP to one 8B eightbyte (str/slice keep
|
||||
// their 24B header), per the tuple-slot ruling and tupeslot's
|
||||
|
||||
@@ -39221,6 +39221,22 @@ fn paramfieldsize(t: *node) i32 = {
|
||||
// tyslicesize() is the slice-header SSoT (rule-13); cstage reads the
|
||||
// same width via tp->type->size (cmd/w6c/cgen.c N_FORRANGE).
|
||||
if (k == nkind.N_TSLICE) { return tyslicesize(): i32; };
|
||||
// #53: a tagged-union tuple-field carries its full box (tag + widest
|
||||
// payload, slot-padded), NOT the 8B scalar default — a for-range
|
||||
// destructure binding sized 8 loaded only the tag word (cs=56/ww=9, the
|
||||
// cat-A repro). The box width is variant-dependent, so read it from the
|
||||
// checker-stamped tinfo (rule-13): cstage's tp->type->size reads the same
|
||||
// resolved width. The stamp already collapsed any alias, so this also
|
||||
// covers an N_TNAME field naming a tagged union (paramfieldsize's no-`c`
|
||||
// structural contract can't aliaslookup-chase the node). Mirrors the
|
||||
// N_TSLICE arm's type-table SSoT.
|
||||
let tgi: *tinfo = t.type_: *tinfo;
|
||||
if (tgi != nil) {
|
||||
tgi = tichase(tgi);
|
||||
if (tgi != nil && tgi.kind == tykind.TY_TAGGED) {
|
||||
return tgi.size: i32;
|
||||
};
|
||||
};
|
||||
// #43 (F7-c4): a nested tuple field sizes as the sum of its element
|
||||
// SLOTS — each element floored UP to one 8B eightbyte (str/slice keep
|
||||
// their 24B header), per the tuple-slot ruling and tupeslot's
|
||||
|
||||
Reference in New Issue
Block a user