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:
@@ -2910,6 +2910,21 @@ check_file(Checker *c, Node *file)
|
||||
&& !arrlit_init_fits(c, d->type, d->rhs))
|
||||
err(c, d->pos, "let %s init not assignable",
|
||||
d->str);
|
||||
/* #133: const-fold a const-EXPR rhs (N_BIN /
|
||||
* unary-over-N_BIN / def-ref) to a literal so
|
||||
* cgen's literal-only DATA emitter lays the row,
|
||||
* 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 0 silently and is left untouched).
|
||||
* Stamp LAST — the assignability check above
|
||||
* consumes the pre-stamp cexpr type. */
|
||||
u64 dv;
|
||||
if (d->rhs && !fold_int_literal(d->rhs, &dv)
|
||||
&& eval_def_const(c, d->rhs, &dv, 0))
|
||||
stamp_intlit(c, d->rhs, dv);
|
||||
} else if (d->type && d->type->kind == TY_ARRAY
|
||||
&& d->type->alen == 0) {
|
||||
/* `let x: [_]T;` — no initialiser, length can't be
|
||||
|
||||
Reference in New Issue
Block a user