wcc: stamp un-suffixed f32-context float literals (#104 fold-2)

fold-1 narrows a float literal at materialisation only when its node
already carries an f32 type — the `f32` suffix. The common un-suffixed
case `let x: f32 = 1.0` stays ty_untyped_float through the checker, so
the node is never f32-typed: the literal materialises as a 64-bit double
and the f32 consumer reads the low 4 bytes (0.0f for clean values).

Stamp such a literal f32 when an f32 target type is in context, the way
harec's lower_implicit_cast does (ref/harec/src/check.c:148): a float
literal's bit pattern is target-dependent, unlike a width-agnostic int
immediate, so the value-producing node must carry the type. Scoped to
untyped_float -> f32 only (f64 already works via cgen's double default).

coerce_floatlit (cstage clet + cstmt N_RETURN) / coercefloatlit (wwstage
resolvewalk's post-order N_LET / N_RETURN handler) are logically
identical. The wwstage stamp is placed AFTER the child re-walk: the
post-order exprtype dispatch re-stamps a bare N_FLOATLIT back to
untyped_float, so coercing earlier (checkletassign) would be undone.

Scope is let-init and return ONLY, aligned down to the leaner wwstage
(rule 10). The wwstage cgen's exprfloatkind hardcodes a float literal to
f64 and cgbin / the unary negate pick f32 off the operands, not the node
stamp — so a stamped literal in an arith-binop / behind a unary minus
narrows in cstage (ADDSS) but not wwstage (ADDSD), a byte-id break. The
wwstage checker also has no assign / param-typed call-arg / per-field
struct-lit site. binop, unary-minus, assign, call-arg, struct-field wait
on #120 (wwstage cgen + checker build-out).

965_f32stamp_run: cstage run + cs==ww byte-id over un-suffixed let-init
and return literals, the hole 964 left open. Regen w6c/wwdump
combined.ww embeds.
This commit is contained in:
2026-05-26 12:06:47 +09:00
parent acaf0152da
commit a1dff13ec1
6 changed files with 374 additions and 0 deletions

View File

@@ -333,6 +333,7 @@ TESTS = $(BIN)/test_smoke $(BIN)/test_lex $(BIN)/test_parse $(BIN)/test_check \
$(BIN)/test_tuprecv_run \
$(BIN)/test_f64xmm_run \
$(BIN)/test_f32lit_run \
$(BIN)/test_f32stamp_run \
$(BIN)/test_tuprecv_f64_run \
$(BIN)/test_floats_run \
$(BIN)/test_size_type_run \
@@ -1139,6 +1140,11 @@ $(BIN)/test_f32lit_run: test/wcc/964_f32lit_run.c $(BIN)/ww \
$(LIB)/libwwrt.a | $(BIN)
$(CC) $(CFLAGS) -o $@ $<
$(BIN)/test_f32stamp_run: test/wcc/965_f32stamp_run.c $(BIN)/ww \
$(BIN)/w6c $(BIN)/w6c_ww $(BIN)/w6a $(BIN)/w6l \
$(LIB)/libwwrt.a | $(BIN)
$(CC) $(CFLAGS) -o $@ $<
$(BIN)/test_tuprecv_f64_run: test/wcc/956_tuprecv_f64_run.c $(BIN)/ww \
$(BIN)/w6c $(BIN)/w6c_ww $(BIN)/w6a $(BIN)/w6l \
$(LIB)/libwwrt.a | $(BIN)