w6c+w6c_ww: tagged widen-store struct-literal slice field keeps the 3-word header
The cg_widen_tagged_store / cgwidentaggedstorebp struct-payload arm
gated the 3-word {ptr,len,cap} field store on TY_STR only; a slice-
typed field inside a union-payload struct literal fell to the scalar
tail and silently dropped .len/.cap (the #24 gap's widener twin, both
stages symmetric so byte-id gates were blind). Surfaced by #38's
regex-shaped consumer: wide{xs: []u8, ys: []u8, n} widened into
(wide | error | nomem).
This commit is contained in:
@@ -2343,9 +2343,16 @@ cg_widen_tagged_store(Cg *c, Local **locals_p, Type *dst, Node *src,
|
|||||||
}
|
}
|
||||||
Type *fu = (ftype && ftype->kind == TY_NAMED)
|
Type *fu = (ftype && ftype->kind == TY_NAMED)
|
||||||
? ftype->under : ftype;
|
? ftype->under : ftype;
|
||||||
if (fu && fu->kind == TY_STR) {
|
/* str IS []u8 and a slice is the same 3-word
|
||||||
/* str IS []u8: 3-word field (ptr,len,cap)
|
* {ptr,len,cap} header from cgexpr's AX/BX/CX
|
||||||
* from cgexpr's AX/BX/CX (#1/Phase 3). */
|
* (#1/Phase 3). The slice arm rides #38's
|
||||||
|
* regex-shaped consumer (slice fields inside a
|
||||||
|
* union-payload struct literal); the prior
|
||||||
|
* str-only gate dropped .len/.cap via the
|
||||||
|
* scalar store below — the #24 gap's widener
|
||||||
|
* twin. */
|
||||||
|
if (fu && (fu->kind == TY_STR
|
||||||
|
|| fu->kind == TY_SLICE)) {
|
||||||
ins2(c, A_MOVQ, areg(D_AX),
|
ins2(c, A_MOVQ, areg(D_AX),
|
||||||
amem(D_BP, write_off + 8 + (int)foff + 0));
|
amem(D_BP, write_off + 8 + (int)foff + 0));
|
||||||
ins2(c, A_MOVQ, areg(D_BX),
|
ins2(c, A_MOVQ, areg(D_BX),
|
||||||
|
|||||||
@@ -18899,10 +18899,15 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s
|
|||||||
emitline("\tX0, ");
|
emitline("\tX0, ");
|
||||||
emitoff((slot_off + 8 + fi.foff): i64);
|
emitoff((slot_off + 8 + fi.foff): i64);
|
||||||
emitline("(BP)\n");
|
emitline("(BP)\n");
|
||||||
} else { if (isstrtype(c, fi.tnode)) {
|
} else { if (isstrtype(c, fi.tnode)
|
||||||
// str IS []u8: 3-word field
|
|| isslicetype(c, fi.tnode)) {
|
||||||
// (ptr,len,cap) from cgexpr's
|
// str IS []u8 and a slice is the
|
||||||
// AX/BX/CX (#1/Phase 3).
|
// same 3-word {ptr,len,cap} header
|
||||||
|
// from cgexpr's AX/BX/CX (#1/Phase
|
||||||
|
// 3). Slice arm rides #38's regex-
|
||||||
|
// shaped consumer — the prior str-
|
||||||
|
// only gate dropped .len/.cap (#24
|
||||||
|
// gap's widener twin).
|
||||||
emitline("\tMOVQ\tAX, ");
|
emitline("\tMOVQ\tAX, ");
|
||||||
emitoff((slot_off + 8 + fi.foff): i64);
|
emitoff((slot_off + 8 + fi.foff): i64);
|
||||||
emitline("(BP)\n");
|
emitline("(BP)\n");
|
||||||
|
|||||||
@@ -3207,10 +3207,15 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s
|
|||||||
emitline("\tX0, ");
|
emitline("\tX0, ");
|
||||||
emitoff((slot_off + 8 + fi.foff): i64);
|
emitoff((slot_off + 8 + fi.foff): i64);
|
||||||
emitline("(BP)\n");
|
emitline("(BP)\n");
|
||||||
} else { if (isstrtype(c, fi.tnode)) {
|
} else { if (isstrtype(c, fi.tnode)
|
||||||
// str IS []u8: 3-word field
|
|| isslicetype(c, fi.tnode)) {
|
||||||
// (ptr,len,cap) from cgexpr's
|
// str IS []u8 and a slice is the
|
||||||
// AX/BX/CX (#1/Phase 3).
|
// same 3-word {ptr,len,cap} header
|
||||||
|
// from cgexpr's AX/BX/CX (#1/Phase
|
||||||
|
// 3). Slice arm rides #38's regex-
|
||||||
|
// shaped consumer — the prior str-
|
||||||
|
// only gate dropped .len/.cap (#24
|
||||||
|
// gap's widener twin).
|
||||||
emitline("\tMOVQ\tAX, ");
|
emitline("\tMOVQ\tAX, ");
|
||||||
emitoff((slot_off + 8 + fi.foff): i64);
|
emitoff((slot_off + 8 + fi.foff): i64);
|
||||||
emitline("(BP)\n");
|
emitline("(BP)\n");
|
||||||
|
|||||||
@@ -18899,10 +18899,15 @@ fn cgwidentaggedstorebp(c: *cgen, dst: *tinfo, src: *node, slot_off: i32, slot_s
|
|||||||
emitline("\tX0, ");
|
emitline("\tX0, ");
|
||||||
emitoff((slot_off + 8 + fi.foff): i64);
|
emitoff((slot_off + 8 + fi.foff): i64);
|
||||||
emitline("(BP)\n");
|
emitline("(BP)\n");
|
||||||
} else { if (isstrtype(c, fi.tnode)) {
|
} else { if (isstrtype(c, fi.tnode)
|
||||||
// str IS []u8: 3-word field
|
|| isslicetype(c, fi.tnode)) {
|
||||||
// (ptr,len,cap) from cgexpr's
|
// str IS []u8 and a slice is the
|
||||||
// AX/BX/CX (#1/Phase 3).
|
// same 3-word {ptr,len,cap} header
|
||||||
|
// from cgexpr's AX/BX/CX (#1/Phase
|
||||||
|
// 3). Slice arm rides #38's regex-
|
||||||
|
// shaped consumer — the prior str-
|
||||||
|
// only gate dropped .len/.cap (#24
|
||||||
|
// gap's widener twin).
|
||||||
emitline("\tMOVQ\tAX, ");
|
emitline("\tMOVQ\tAX, ");
|
||||||
emitoff((slot_off + 8 + fi.foff): i64);
|
emitoff((slot_off + 8 + fi.foff): i64);
|
||||||
emitline("(BP)\n");
|
emitline("(BP)\n");
|
||||||
|
|||||||
Reference in New Issue
Block a user