// glob_ptr_field_test — a scalar field store through a module-GLOBAL `*struct` // pointer (`gp.f = v`) must load the pointer value from gp(SB), not deref the // saved-BP word, migrated from test/wcc/989_globptrfield_run.c (inverse-set // #47, report-item [58]). cstage's N_DOT-lhs via_ptr scalar store loaded the // base with `MOVQ boff(BP),BX`; for a module-global base boff==0, so it emitted // `MOVQ (BP),BX` — derefing saved BP as the pointer → store through garbage → // SEGV. wwstage was already correct (LEAQ gp(SB),BX; MOVQ (BX),BX); the cstage // half aligned UP and the .s is byte-identical, so a behavioral @test is the // net. backing is a fresh (zeroed) global; a store that lands in garbage never // writes the symbol, so a read-back of backing's field catches the miss. The // static-init form `let gp: *S = &backing;` is #48-blocked, so the runtime // `gp = &backing` form is used (as in the C twin). package glob_ptr_field_test; type S = struct { f: i64, g: i64 }; let backing: S = S { f = 0, g = 0 }; let gp: *S = nil; @test fn store_off0() void = { // the exact #58 repro: field at offset 0 through the global pointer. gp = &backing; gp.f = 7; assert(backing.f: i32 == 7); };