wcc/check: #133 const-expr scalar module-global — fold+stamp let-init like def, emit DATA (both stages)
A module-global let with a const-expr init (let s = 7*6) emitted NO DATA word: cstage LINK-FAILed (undefined main.s, loud), wwstage was SILENT (no DATA, MOVSXD on stale AX, exit 152). The DEF pass-2 arm already const-folds + stamps its rhs to N_INTLIT (the #88 eval_def_const/stamp_intlit machinery); the LET pass-2 arm omitted it. Mirror it: after the assignability check, fold the rhs and stamp N_INTLIT when the plain-literal fold missed AND the const-fold succeeded. The existing DATA-emit downstream then fires (DATAW 42 + load). Both stages, byte-identical. Closes the inferred const-expr global and the typed b-ii case (let s:i64=7*6, link-fail both stages) with one stamp. Gated on genuine int-const success (the eval return value, not the out-param): str/struct/slice/call/runtime-operand rhs short-circuit before the stamp and are left untouched — never zeroed. Non-const rhs stays on its current loud route; div-by-zero stays loud. Latent in selfhost (no const-expr module globals → 990-997 byte-id unchanged). Pin: 947 rows C1 inferred 7*6, C2 typed b-ii, C3 def-ref K*7, C4 unary-over-binop, C5 div-by-zero loud-guard; cs==ww byte-id.
This commit is contained in:
@@ -15443,6 +15443,24 @@ export fn checkfile(c: *checker, file: *node) void = {
|
||||
// were missed). Needed for the array accept-if-fits
|
||||
// range-check to fire on module-level `let A:[N]u8=[..]`.
|
||||
checkletassign(c, d);
|
||||
// #133: const-fold a const-EXPR rhs (N_BIN /
|
||||
// unary-over-N_BIN / def-ref) to a literal so cgen's
|
||||
// literal-only emitletdataw lays the DATA row +
|
||||
// defaultinferredlets recognises it, mirroring the
|
||||
// N_DEF arm above. GATED on the plain literal fold
|
||||
// missing first (existing literal/unary-literal lets
|
||||
// keep their node, byte-identical) AND the const-fold
|
||||
// succeeding (a str/struct/slice/call/runtime-operand
|
||||
// rhs returns false silently and is left untouched).
|
||||
// Stamp LAST — checkletassign consumes the pre-stamp type.
|
||||
if (d.rhs != nil) {
|
||||
let dv: u64 = 0u64;
|
||||
if (!foldintliteral(d.rhs, &dv)) {
|
||||
if (evaldefconst(c, d.rhs, &dv, 0)) {
|
||||
stampintlit(d.rhs, dv);
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
d = d.next;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user