selfhost+test: strlit-inline str-def value-load shape (#12)

Class A silent miscompile. wwstage cgenexpr.ww cgident's bare-ident
deflookup→true branch and cgdot's module-qualified leaf branch
emitted `MOVQ <mod>.<name>(SB), AX` for a `def MSG: str = "..."`
value reference — a load from a SB symbol that emit_data never
writes. Str defs are not laid out at SB; they live as interned
strlits the .ptr/.len fold (post-#4c) and value-load consume.
Cstage already strlit-inlines via Sdef walks #1 (case N_IDENT
non-local) and #2 (case N_DOT untyped-lhs); wwstage now matches
the (LEAQ _S_<n>(SB), MOVQ $<len>, BX) emit shape per rule 10.

Surfaced by reviewer-def during #4c R3 while attempting option (B)
for the cstage Sdef walks #1/#2 prefer-pass — both walks'
cs-vs-ws byte-id sentinel rows could not pass while wwstage
emitted the bogus DATAW shape. Filed as #12 and deferred until
the wwstage emit shape was fixed. Unblocks #11 + #13 (cstage
prefer-pass graduations).

Latent: no in-tree corpus referenced a str def as a value (only
as .ptr/.len via cgdot field-fold) prior to lib/strings c3 —
same corpus-coverage-blind shape as the #4a-#4e graduations.

746_strdef_inline pins both sites with 2 rows: bare ident +
mod-qualified. Each row asserts `LEAQ _S_` + `MOVQ $<strlit_len>,`
inside the caller TEXT before RET, anti-checks the pre-fix
`<mod>.<name>(SB)` symbol-load, and cs-vs-ws byte-id per row.

120/120 ok. ww2 == ww3 == ww4 byte-id holds.
This commit is contained in:
2026-05-18 23:56:58 +09:00
parent 049ebc14a1
commit d985622cb1
5 changed files with 354 additions and 0 deletions

View File

@@ -280,6 +280,7 @@ TESTS = $(BIN)/test_smoke $(BIN)/test_lex $(BIN)/test_parse $(BIN)/test_check \
$(BIN)/test_fnparams_bare_leaf_shadow \
$(BIN)/test_fnret_bare_leaf_shadow \
$(BIN)/test_fnret34_modshadow \
$(BIN)/test_strdef_inline \
$(BIN)/test_param_shadow_mod \
$(BIN)/test_localoff_scope \
$(BIN)/test_cast_enum_movl \
@@ -689,6 +690,10 @@ $(BIN)/test_fnret34_modshadow: test/wcc/745_fnret34_modshadow.c \
$(BIN)/w6c $(BIN)/w6c_ww | $(BIN)
$(CC) $(CFLAGS) -o $@ $<
$(BIN)/test_strdef_inline: test/wcc/746_strdef_inline.c \
$(BIN)/w6c $(BIN)/w6c_ww | $(BIN)
$(CC) $(CFLAGS) -o $@ $<
$(BIN)/test_match_4arm_cross_module_run: test/wcc/929_match_4arm_cross_module_run.c \
$(BIN)/ww $(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \
$(BIN)/ww_ww $(BIN)/w6c_ww $(BIN)/w6a_ww $(BIN)/w6l_ww \