`t[i].cap` (t a `[N][]u8` / `[N]str`) miscompiled in BOTH stages, divergently — the read-side sibling of #20's store fix. cgexpr on the indexed element leaves the full {ptr,len,cap} header (AX/BX/CX via cgslicehdr), but the `.cap` field-selector never shuffled CX→AX: cstage's typed pseudo-field else-branch handled only .ptr/.len, so `.cap` fell through returning AX=.ptr; wwstage's cgdot non-ident catch-all likewise handled only .ptr/.len, emitting no read (stale AX). `t[i].len` already worked (BX→AX shuffle) — only `.cap` was missing. Fix mirrors the .len shuffle: add the .cap CX→AX arm in both stages. The shuffle fires ONLY for a typed slice/str base (TY_SLICE/TY_STR after NAMED-chase); an untyped str literal (`"abc".cap`) leaves only AX=ptr/BX=len and must return AX unshuffled — keeping the wwstage catch-all byte-identical with cstage, whose cap-shuffle lives in the typed branch, not the untyped catch-all. Validated direct `t[i].cap` (slice + str, elements 0/1) against the whole-element-copy oracle (`let q=t[i]; q.cap`, made correct by #20), plus .len-after-index regression pins, in test 683; dual-stage runtime + byte-id (36/36 ok). combined.ww regenerated.
This commit is contained in:
@@ -7991,12 +7991,20 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
areg(D_AX));
|
||||
} else {
|
||||
/* Evaluate the str/slice expression — leaves
|
||||
* (AX=ptr, BX=len) for str. .ptr returns AX,
|
||||
* .len shuffles BX→AX. */
|
||||
* the full (AX=ptr, BX=len, CX=cap) header
|
||||
* (cgslicehdr) for an indexed element / non-ident
|
||||
* base. .ptr returns AX, .len shuffles BX→AX,
|
||||
* .cap shuffles CX→AX. The .cap shuffle is the
|
||||
* #13 read-fix (sibling of the #20 store): pre-fix
|
||||
* the else-arm handled only .len, so `t[i].cap`
|
||||
* fell through returning AX=.ptr. */
|
||||
cgexpr(c, n->lhs, locals);
|
||||
if (lenfld)
|
||||
ins2(c, A_MOVQ, areg(D_BX),
|
||||
areg(D_AX));
|
||||
else if (capfld)
|
||||
ins2(c, A_MOVQ, areg(D_CX),
|
||||
areg(D_AX));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user