cgen: fix global-ptr field READ, load ptr value via SB before offset (#15)

Reading gp.f through a module-global pointer miscompiled in BOTH stages,
differently: cstage classified gp as a local at boff 0 and derefed BP
(MOVQ (BP),BX), wwstage collapsed gp.f to an undefined global symbol f
(MOVQ f(SB)). Both now load the pointer value from the global's data slot
before the field offset, converging on MOVQ gp(SB),BX; MOVQ off(BX),AX.
cstage mirrors the #6 store decline; wwstage gains a global-ptr arm and
shares a cgptrfieldload helper with the local arm.

Fused, not split: the two stages must emit byte-identical asm, so a
one-stage commit would fail the byte-id gate. Sibling byte-divergences
filed: #16 (chained-spine gp.x.y), #17 (>32B tagged word-order).

Test: table-driven 689_globptr_field_read_run (24 rows, runtime + byte-id).
This commit is contained in:
2026-06-23 06:42:38 +09:00
parent 02967e04ce
commit 475c003b0d
4 changed files with 399 additions and 59 deletions

View File

@@ -326,6 +326,7 @@ TESTS = $(BIN)/test_smoke $(BIN)/test_lex $(BIN)/test_parse $(BIN)/test_check \
$(BIN)/test_structlit_slice_field \
$(BIN)/test_arrglob_nodup_run \
$(BIN)/test_globptr_field_store_run \
$(BIN)/test_globptr_field_read_run \
$(BIN)/test_dot_str_chained_arg \
$(BIN)/test_dot_slice_arg \
$(BIN)/test_dot_tagged_source \
@@ -1458,6 +1459,16 @@ $(BIN)/test_globptr_field_store_run: test/wcc/689_globptr_field_store_run.c $(BI
$(LIB)/libwwrt.a | $(BIN)
$(CC) $(CFLAGS) -o $@ $<
# 689_globptr_field_read_run (#15): reading a field through a module-global
# *struct ptr base (single-dot `gp.f`) no longer SEGVs in cstage / collapses
# to a bare symbol in wwstage; both load the ptr value via SB then the field
# offset, byte-identically. Read twin of 689_globptr_field_store_run.
$(BIN)/test_globptr_field_read_run: test/wcc/689_globptr_field_read_run.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 $@ $<
$(BIN)/test_dot_str_chained_arg: test/wcc/692_dot_str_chained_arg.c $(BIN)/ww \
$(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \
$(BIN)/ww_ww $(BIN)/w6c_ww $(BIN)/w6a_ww $(BIN)/w6l_ww \