wcc/ww: alloc of an alias struct literal chases the alias for size and fill
alloc(alias{...}) keyed the size and field-fill off the syntactic
alias name — it under-allocated and emitted zero field stores. Chase
the alias via structlookupchain to the resolved struct (depth-2
chains verified). The scalar else-branch keeps its pre-existing
benign cs!=ww divergence, surfaced here and deferred as task #57
(site note at the arm). Review item #26.
This commit is contained in:
@@ -28927,14 +28927,14 @@ fn cgalloc(c: *cgen, n: *node) void = {
|
||||
let sz: i32 = 8;
|
||||
let si: *structinfo = nil;
|
||||
if (v.kind == nkind.N_STRUCTLIT) {
|
||||
let trefn: *node = v.lhs;
|
||||
let sname: str;
|
||||
sname.ptr = nil; sname.len = 0;
|
||||
if (trefn != nil) {
|
||||
if (trefn.kind == nkind.N_IDENT) { sname = trefn.str; }
|
||||
else { if (trefn.kind == nkind.N_TNAME) { sname = trefn.str; }; };
|
||||
};
|
||||
si = structlookup(c, sname);
|
||||
// #26: chase the alias chain on the literal's type ref so an
|
||||
// alias head (`type pt = point; alloc(pt{...})`) resolves to
|
||||
// the underlying struct's layout — name-keyed structlookup on
|
||||
// the syntactic head missed it (under-alloc $8 + zero field
|
||||
// stores). Mirrors cstage cgen.c:8223-8240 (type_default chases
|
||||
// named before sizing/walking fields); same alias-chase helper
|
||||
// the #22 sites use.
|
||||
si = structlookupchain(c, v.lhs);
|
||||
if (si != nil) { sz = si.totsize; };
|
||||
};
|
||||
let okl: str = mklabel(c, "alloc_ok");
|
||||
@@ -29010,6 +29010,10 @@ fn cgalloc(c: *cgen, n: *node) void = {
|
||||
};
|
||||
};
|
||||
} else {
|
||||
// #57 (retained cs!=ww, deferred): scalar/ptr alloc keeps the
|
||||
// default-8 size + MOVQ store; cstage sizes the scalar exactly
|
||||
// ($1/MOVB for u8) and the latent alloc(str|slice) wants 24B not 8.
|
||||
// Byte-id-visible, runtime-benign; not folded into the #26 arm.
|
||||
cgexpr(c, v);
|
||||
emitline("\tMOVQ\t(SP), BX\n");
|
||||
let sop: str = "MOVQ";
|
||||
|
||||
@@ -5707,14 +5707,14 @@ fn cgalloc(c: *cgen, n: *node) void = {
|
||||
let sz: i32 = 8;
|
||||
let si: *structinfo = nil;
|
||||
if (v.kind == nkind.N_STRUCTLIT) {
|
||||
let trefn: *node = v.lhs;
|
||||
let sname: str;
|
||||
sname.ptr = nil; sname.len = 0;
|
||||
if (trefn != nil) {
|
||||
if (trefn.kind == nkind.N_IDENT) { sname = trefn.str; }
|
||||
else { if (trefn.kind == nkind.N_TNAME) { sname = trefn.str; }; };
|
||||
};
|
||||
si = structlookup(c, sname);
|
||||
// #26: chase the alias chain on the literal's type ref so an
|
||||
// alias head (`type pt = point; alloc(pt{...})`) resolves to
|
||||
// the underlying struct's layout — name-keyed structlookup on
|
||||
// the syntactic head missed it (under-alloc $8 + zero field
|
||||
// stores). Mirrors cstage cgen.c:8223-8240 (type_default chases
|
||||
// named before sizing/walking fields); same alias-chase helper
|
||||
// the #22 sites use.
|
||||
si = structlookupchain(c, v.lhs);
|
||||
if (si != nil) { sz = si.totsize; };
|
||||
};
|
||||
let okl: str = mklabel(c, "alloc_ok");
|
||||
@@ -5790,6 +5790,10 @@ fn cgalloc(c: *cgen, n: *node) void = {
|
||||
};
|
||||
};
|
||||
} else {
|
||||
// #57 (retained cs!=ww, deferred): scalar/ptr alloc keeps the
|
||||
// default-8 size + MOVQ store; cstage sizes the scalar exactly
|
||||
// ($1/MOVB for u8) and the latent alloc(str|slice) wants 24B not 8.
|
||||
// Byte-id-visible, runtime-benign; not folded into the #26 arm.
|
||||
cgexpr(c, v);
|
||||
emitline("\tMOVQ\t(SP), BX\n");
|
||||
let sop: str = "MOVQ";
|
||||
|
||||
@@ -28927,14 +28927,14 @@ fn cgalloc(c: *cgen, n: *node) void = {
|
||||
let sz: i32 = 8;
|
||||
let si: *structinfo = nil;
|
||||
if (v.kind == nkind.N_STRUCTLIT) {
|
||||
let trefn: *node = v.lhs;
|
||||
let sname: str;
|
||||
sname.ptr = nil; sname.len = 0;
|
||||
if (trefn != nil) {
|
||||
if (trefn.kind == nkind.N_IDENT) { sname = trefn.str; }
|
||||
else { if (trefn.kind == nkind.N_TNAME) { sname = trefn.str; }; };
|
||||
};
|
||||
si = structlookup(c, sname);
|
||||
// #26: chase the alias chain on the literal's type ref so an
|
||||
// alias head (`type pt = point; alloc(pt{...})`) resolves to
|
||||
// the underlying struct's layout — name-keyed structlookup on
|
||||
// the syntactic head missed it (under-alloc $8 + zero field
|
||||
// stores). Mirrors cstage cgen.c:8223-8240 (type_default chases
|
||||
// named before sizing/walking fields); same alias-chase helper
|
||||
// the #22 sites use.
|
||||
si = structlookupchain(c, v.lhs);
|
||||
if (si != nil) { sz = si.totsize; };
|
||||
};
|
||||
let okl: str = mklabel(c, "alloc_ok");
|
||||
@@ -29010,6 +29010,10 @@ fn cgalloc(c: *cgen, n: *node) void = {
|
||||
};
|
||||
};
|
||||
} else {
|
||||
// #57 (retained cs!=ww, deferred): scalar/ptr alloc keeps the
|
||||
// default-8 size + MOVQ store; cstage sizes the scalar exactly
|
||||
// ($1/MOVB for u8) and the latent alloc(str|slice) wants 24B not 8.
|
||||
// Byte-id-visible, runtime-benign; not folded into the #26 arm.
|
||||
cgexpr(c, v);
|
||||
emitline("\tMOVQ\t(SP), BX\n");
|
||||
let sop: str = "MOVQ";
|
||||
|
||||
Reference in New Issue
Block a user