wcc/cgen: zero-init sub-8-byte bare lets, both stages; bytes test honest (#16-team)

A bare 'let x: T;' with 1 <= size(T) <= 7 matched no zero-fill arm in
either stage (8B and >8B were already zeroed) - 'let c: [3]u8;' read
stack garbage. User-ruled zero-value semantics: cstage gate sz>8 ->
sz>0; wwstage zsz==8 arm hoisted above the fill-run arm (required -
8B would otherwise route into the run and diverge) and run gate
zsz>0. New 840 pin: dirty-frame probe rows, dual-dim (run + cs/ww
byte-id); discriminators fail exit-154 on pre-fix binaries.

Fused with the lib/bytes test conversion (rule 11): either half alone
turns 967 red. The old exit(signalled+10) wrapped a real 1782-count
ltrim failure to exit 0 - green depended on the garbage. Converted to
assert form (completes the 35/35 @test conversion); ltrim rows keep
the bare 'let c: [3]u8;' as the consumer proof of the fix.
This commit is contained in:
2026-06-10 20:08:58 +09:00
parent 3e2bf0612e
commit 5b212e51cf
7 changed files with 527 additions and 276 deletions

View File

@@ -440,6 +440,7 @@ TESTS = $(BIN)/test_smoke $(BIN)/test_lex $(BIN)/test_parse $(BIN)/test_check \
$(BIN)/test_litstr_pseudo_run \
$(BIN)/test_lenidx_run \
$(BIN)/test_globalidx_run \
$(BIN)/test_zeroinit_run \
$(BIN)/test_tuple_sret_callee \
$(BIN)/test_tuple_sret_receive_run \
$(BIN)/test_append_wide_elem \
@@ -1207,6 +1208,16 @@ $(BIN)/test_globalidx_run: test/wcc/803_globalidx_run.c \
$(LIB)/libwwrt.a | $(BIN)
$(CC) $(CFLAGS) -o $@ $<
# #16: a bare `let x: T;` (no rhs) must zero-fill its slot. cgen emitted
# the zero-fill only for 8B-primitive and >8B-composite slots — a SUB-8
# aggregate (`let c: [3]u8;`) fell through to NOTHING and read stack
# garbage (cstage == wwstage, gate-blind; ken's bytes-967 root cause).
# Runtime (cstage dirty()→probe()) + cs==ww byte-id, both dimensions/row.
$(BIN)/test_zeroinit_run: test/wcc/840_zeroinit_run.c \
$(BIN)/ww $(BIN)/w6c $(BIN)/w6c_ww $(BIN)/w6a $(BIN)/w6l \
$(LIB)/libwwrt.a | $(BIN)
$(CC) $(CFLAGS) -o $@ $<
# #10 Fold A (wide tuple-return / sret, CALLEE side): an over-cap tuple
# return (> 4 GP or > 2 SSE eightbytes) now compiles via sret instead of
# loud-stopping at the SEND. Compile + cs==ww byte-id only — the receive