wcc: retire exprfloatkind, read the checker stamp directly

exprfloatkind was wwstage cgen's structural float-classifier — a workaround for
the checker stamp being untrustworthy. With the previous commit arming the
asserttyped bail, every checked value-node is now stamped (or cited-exempt),
so its job collapses to a 2-liner reading n.type_ — the same path cstage cgen
has always taken. Retire it: inline the stamp-read at its eight sites (cgcast,
cgun, cgbin lhs+rhs, cgcall pop, pushargsrev, cgwidentaggedstorebp, cgreturn
x2 collapsed), delete the wrapper, and delete the two residual
sibling-evidence loud-aborts (cgbin float-arith, cgwidentaggedstorebp
float-arm) — their operands are real source value-exprs the armed bail now
stamps, so the guards can never fire.

One synth-post-checker value-node remained outside the bail's reach: the
variadic-slice descriptor pushed in pushargsrev/cgcall (cgenexpr.ww). Stamp
it at synthesis with the variadic param's []T slice tinfo so the inlined
reads see a stamped node, no nil special-case. Byte-id-neutral by design
(slice tinfo and nil both read non-float); 990-997 confirm.

Closes the bail-rearm arc — wwstage now reads the same float-class SSoT
cstage does, the gate-blind float-classification family is closed, and the
build+test corpus is asserttyped-clean by construction.
This commit is contained in:
2026-05-28 11:35:45 +09:00
parent 719893743e
commit d92c199d25
5 changed files with 222 additions and 363 deletions

View File

@@ -473,6 +473,14 @@ fn cgreturn(c: *cgen, n: *node) void = {
// IMULQ before the call) does not land in slot+16 /
// slot+24. (Task #18.)
let rsz: i32 = slotsize(c, c.fnret);
// Value-class read off the checker stamp (rhs.type_) —
// the SSoT cstage reads via node_isfloat / type_isf32.
let rfk: i32 = 0;
if (rhs != nil) {
let rety: *tinfo = rhs.type_: *tinfo;
if (typeisf32(rety)) { rfk = 1; }
else { if (typeisfloat(rety)) { rfk = 2; }; };
};
if (nodeisslice(c, rhs)) {
// cgexpr leaves (AX=ptr, BX=len, CX=cap).
// Shuffle into return ABI: DX=ptr, CX=len,
@@ -487,7 +495,7 @@ fn cgreturn(c: *cgen, n: *node) void = {
emitline("\tMOVQ\tCX, R8\n");
emitline("\tMOVQ\tBX, CX\n");
emitline("\tMOVQ\tAX, DX\n");
} else { if (exprfloatkind(c, rhs) != 0) {
} else { if (rfk != 0) {
// #157: float variant — cgexpr left the value
// in X0, not AX. No MOVQ-xmm->gp encoding, so
// bridge X0->DX through a stack slot (same arg-
@@ -500,7 +508,7 @@ fn cgreturn(c: *cgen, n: *node) void = {
emitline("\tSUBQ\t$8, SP\n");
emitline("\tMOVQ\t$0, (SP)\n");
let mov: str = "MOVSD";
if (exprfloatkind(c, rhs) == 1) { mov = "MOVSS"; };
if (rfk == 1) { mov = "MOVSS"; };
emitline("\t");
emitline(mov);
emitline("\tX0, (SP)\n");