Files
ww/test/lang/heapptr_dotread_test.ww
Hojun-Cho d78137a051 w6c: fold dot chains through inferred-alloc struct pointers (#24 residue)
wwstage dotchainresolve gated its *T roots on an N_TPTR-over-N_TNAME
tnode; an inferred `let p = alloc(S{...})!` rides the checker-
SYNTHESIZED N_TPTR whose pointee is the struct BODY node (the #24
TNAME-normalize covers only the direct struct-lit binding), so the
root gate failed and chained p.field.pseudo reads fell to the
unfused deref arms — shape-only divergence vs cstage's type-keyed
fold (both stages runtime-correct; the historical field(SB) leak the
pin described was already fixed). Widen the local and global root
gates to accept the N_TSTRUCT pointee; correctness stays enforced by
the stamped-tinfo peel below (TY_PTR -> pointee TY_STRUCT).

Graduates alias_g73_heapfill out of DATABYTEID_DIVERGED (2 pins
remain, both the tagged-spill family); adds compile fixtures pinning
the newly-converged siblings (nested read+store, slice .cap,
inferred-global root; pin 1730/22/3460) and a runtime lang row that
mutates then re-points the heap base — a read bypassing the pointer
returns the wrong len.
2026-08-08 17:14:59 +09:00

23 lines
653 B
Plaintext

// heapptr_dotread_test — chained field reads through an INFERRED alloc
// pointer must go THROUGH the pointer: mutate the heap str after the
// fill, then re-point the base at a second object — a read that
// bypasses the pointer (stale cached addr or literal-global load)
// returns the wrong len.
package heapptr_dotread_test;
type s1t = str;
type s2t = s1t;
type box = struct { s: s2t, n: int };
@test fn mutate_then_repoint() void = {
let p = alloc(box { s = "hello", n = 5 })!;
assert(p.s.len == 5);
p.s = "worldwide";
assert(p.s.len == 9);
let q = alloc(box { s = "xy", n = 7 })!;
p = q;
assert(p.s.len == 2);
assert(p.n == 7);
};