w6c: receive sub-8 odd-sized by-value struct/array CALL return (#107)
A struct/array sized {3,5,6,7} returned by value fell past every N_LET call-receive arm (the sized-tail arm handles {1,2,4}, the memcpy arm gates on sz>8), so cstage emitted nothing and silently DROPPED the CALL — garbage exit plus a gate-blind cs!=ww divergence (wwstage emitted CALL+MOVQ via its generic let fallback). Align cstage UP: emit the CALL + one MOVQ AX, the SysV single-eightbyte receive (ref/qbe/amd64/sysv.c retr). New table-driven gate 949 (runtime exit oracle on both drivers + cs==ww byte-id; negative-control proven).
This commit is contained in:
@@ -12940,6 +12940,30 @@ cgstmt(Cg *c, Node *n, Local **locals, int *frame)
|
||||
goto letlink;
|
||||
}
|
||||
}
|
||||
/* #107: a struct/array call-receive whose size is a single
|
||||
* eightbyte (< 8B) but NOT one of the sized-tail widths
|
||||
* {1,2,4} — i.e. sz ∈ {3,5,6,7}, reachable via @packed (#51,
|
||||
* e.g. @packed{u8,u32}=5) and natural sub-8 maxalign-1 shapes
|
||||
* (struct{u8,u8,u8}=3) — is ONE INTEGER eightbyte returned in
|
||||
* RAX (ref/qbe/amd64/sysv.c retr: the n*8<size loop runs once).
|
||||
* The producer zero-pads AX to 24B and localslot rounds every
|
||||
* slot up to 8B, so a single full-word MOVQ stores it cleanly.
|
||||
* Pre-fix this size fell past EVERY arm (the sized-tail arm
|
||||
* below excludes these tails; the memcpy arm gates on sz>8) and
|
||||
* cstage emitted NOTHING — the CALL was silently DROPPED, while
|
||||
* wwstage emitted CALL + MOVQ AX via its generic let fallback
|
||||
* (cgenstmt.ww:3007): gate-blind cs≠ww AND a silent miscompile.
|
||||
* Aligns cstage UP to wwstage's SysV-correct single-MOVQ
|
||||
* receive. Task #107. */
|
||||
if (n->rhs && n->rhs->kind == N_CALL && lu
|
||||
&& (lu->kind == TY_STRUCT || lu->kind == TY_ARRAY)
|
||||
&& sz < 8
|
||||
&& (sz % 8 == 3 || sz % 8 == 5
|
||||
|| sz % 8 == 6 || sz % 8 == 7)) {
|
||||
cgexpr(c, n->rhs, *locals);
|
||||
ins2(c, A_MOVQ, areg(D_AX), amem(D_BP, off));
|
||||
goto letlink;
|
||||
}
|
||||
if (n->rhs && n->rhs->kind == N_CALL && lu
|
||||
&& (lu->kind == TY_STRUCT || lu->kind == TY_ARRAY)
|
||||
&& sz <= 24
|
||||
|
||||
Reference in New Issue
Block a user