wcc/cgen: #135 inferred-float module-global — default untyped_float to f64 (wwstage)

let pi = 3.5; pi * 2.0 (an inferred-type float module-global) was silently
miscompiled by wwstage: untyped_float wasn't defaulted, so letemitsize
sized it 0 -> no DATAW emitted -> the pi load was dropped, X0 kept a stale
spill -> 2.0*2.0 = 4 not 7. cstage became correct via #150-B's sym-repoint
(stamps f64 -> MOVSD), so this aligns wwstage UP, byte-identical.

wwstage-only: cgen.ww defaultinferredlets gains the untyped_float->f64 arm
(mirrors the untyped_int->int arm; the codebase's own #135-deferred
carve-out at cgen.ww:1079-1082, unblocked now that #150-B killed the
rule-10 divergence it feared), and cgenexpr.ww cgident gets a letfloatprim
fallback (the same primitive-TNAME SSoT letemitsize already uses, since a
renamed primitive TNAME carries no tinfo stamp). cstage cgen unchanged
(w6c md5 unchanged). int-inferred globals stay integer.

byte-id 990-997 8/8. test/wcc/824 table-driven. The N_CAST-no-recurse
parity (check.c:1276) is filed separately (#19).
This commit is contained in:
2026-06-08 21:46:14 +09:00
parent ebd5b8014c
commit ef6fcbfc04
6 changed files with 398 additions and 6 deletions

View File

@@ -1102,6 +1102,30 @@ fn defaultinferredlets(c: *cgen, file: *node) void = {
d.lhs.str = "int";
};
};
// #135: the inferred-FLOAT twin, now unblocked. The carve-
// out above (deferred to #135) feared a cs≠ww divergence
// because cstage USED to integer-type an inferred float
// (MOVQ); #150-B fixed cstage to type_default untyped_float
// → f64 and load MOVSD, so defaulting here now CONVERGES.
// Without it, letemitsize sees "untyped_float" (not in
// letfloatprim) → 0 → the global is dropped from collectlets
// (no DATAW) and the read falls to cgident's silent bare
// return (X0 untouched). Mirror cstage check.c clet
// type_default.
if (d.lhs != nil && d.rhs != nil
&& d.lhs.kind == nkind.N_TNAME
&& streq(d.lhs.str, "untyped_float")) {
let opnd: *node = d.rhs;
if (opnd.kind == nkind.N_UN
&& (opnd.op == tkind.TK_PLUS
|| opnd.op == tkind.TK_MINUS)) {
opnd = opnd.lhs;
};
if (opnd != nil
&& opnd.kind == nkind.N_FLOATLIT) {
d.lhs.str = "f64";
};
};
};
d = d.next;
};