wwstage: zero-init 8B composite locals in bare-let to match cstage (#213)

wwstage's cglet no-rhs path zero-inited only 8B primitives (MOVQ) and >8B composites (XORQ run), so an 8B *composite* local (single-field struct/tagged, e.g. struct{src:*vtable}) declared bare (let b: box;) was left uninitialized -- reading an unassigned field returned stack garbage (a silent read-before-init), and it diverged from cstage which zero-inits any 8B local (cs!=ww byte-id, surfaced by #5's bufio box{src:io.stream}). Add the missing arm: a non-array composite of size 8 emits MOVQ $0, matching cstage's no-rhs sz==8 zeroing. cstage unchanged (already correct -- align wwstage UP). Scope is 8B-only: cstage does not zero-init sub-8 composites either (sub-8 falls through to nothing on both stages, already cs==ww), so zeroing sub-8 on wwstage would create a new divergence; the sub-8 read-before-init garbage is a separate shared-both-stages latent (#20). Adds test/wcc/790 (8B byte-id row + read-before-init correctness lock reading 0 on both stages). rule-10 align-up; closes the #213 8B-composite slice; unblocks post-eFinal #5.
This commit is contained in:
2026-05-30 09:36:32 +09:00
parent 45e5d74047
commit c4e29df4e9
5 changed files with 295 additions and 3 deletions

View File

@@ -338,6 +338,7 @@ TESTS = $(BIN)/test_smoke $(BIN)/test_lex $(BIN)/test_parse $(BIN)/test_check \
$(BIN)/test_xmod_alias_struct_collide_run \
$(BIN)/test_xmod_variant_match \
$(BIN)/test_named_ptr_alias_variant_widen \
$(BIN)/test_single_field_struct_zeroinit \
$(BIN)/test_structvariant_largeunion_return \
$(BIN)/test_narrow_alias_deref_store \
$(BIN)/test_bufio_vstream_run \
@@ -766,6 +767,15 @@ $(BIN)/test_named_ptr_alias_variant_widen: test/wcc/789_named_ptr_alias_variant_
$(LIB)/libwwrt.a | $(BIN)
$(CC) $(CFLAGS) -o $@ $<
# #213: bare `let b: T;` of an 8B single-field struct must zero-init the
# slot (cstage does; wwstage skipped → read-before-init garbage + 778
# cs!=ww). Both-stage byte-id + a read-before-init correctness row.
$(BIN)/test_single_field_struct_zeroinit: test/wcc/790_single_field_struct_zeroinit.c \
$(BIN)/ww $(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \
$(BIN)/ww_ww $(BIN)/w6c_ww $(BIN)/w6a_ww $(BIN)/w6l_ww \
$(LIB)/libwwrt.a | $(BIN)
$(CC) $(CFLAGS) -o $@ $<
# #9: returning a STRUCT variant of a LARGE (>4-eightbyte) tagged union.
# Both-stage byte-id + runtime (reads tag AND the widened &fn field, so a
# dropped-store regression can't hide behind self-consistent byte-id).