// str_arrfield_cap_test — a str-typed FIELD of an INDEXED element `arr[i].f` // (N_INDEX-rooted N_DOT) must load the full 24B {ptr,len,cap} header, not just // {ptr,len}, migrated from test/wcc/936_str_arrfield_cap_run.c (C4.6 arrfield, // the LAST member of the 3-word-value-read cluster). str is 24B since Phase 2 // (#1); pre-arrfield the `arr[i].f` str arm loaded 2 words (len in BX, ptr in // AX) and dropped cap. The miscompile was cs==ww, so the 990-997 byte-id gates // stayed GREEN while the runtime was wrong — behavioral @test is the net. There // is no adjacent slice-element sibling at this leaf, so the 3-word triple is // authored directly to the canonical slice-header ABI (len->BX, cap->CX, // ptr->AX LAST). // // POISONING: the store side of `arr[i].f = v` is a separate, still-broken // store-side gap (filed; out of scope for this read-side fold). So the value // elements (A, B) are poisoned through `&arr[i]` + a *struct field write, which // lands a real cap into the element's +16 word; D points its element at a // separately-built struct (the proven s1local 3-word field store). // // DISCRIMINATION: a 2-word read leaves CX holding whatever the index scale- // multiply left there, never the poison; spoil() additionally interposes a // CX-clobbering call between the build and the `arr[i].f` read, so a broken // 2-word read observes spoil's leftover (44), never the poison cap. package str_arrfield_cap_test; type rec = struct { f: str }; fn spoil() i32 = { let z: str = "zzzz"; z.cap = 44i32; let w: str = z; return w.cap: i32; }; @test fn arrfield_array_value() void = { // A — `arr[i].f` value element of a [N]rec local array (LEAQ base). // Poison cap=8 (len=2) via &arr[1] + a *struct field store. let p: str = "hi"; p.cap = 8i32; let arr: [3]rec; let pr: *rec = &arr[1]; pr.f = p; let junk: i32 = spoil(); let s: str = arr[1].f; assert(s.cap: i32 == 8); assert(s.len: i32 == 2); assert(junk == 44); }; @test fn arrfield_slice_value() void = { // B — `sl[i].f` value element of a []rec local slice (MOVQ slice.ptr // base) viewing the same poisoned backing array. Poison cap=9 (len=5). let p: str = "world"; p.cap = 9i32; let arr: [3]rec; let pr: *rec = &arr[1]; pr.f = p; let sl: []rec = arr[0:3]; let junk: i32 = spoil(); let s: str = sl[1].f; assert(s.cap: i32 == 9); assert(s.len: i32 == 5); assert(junk == 44); }; @test fn arrfield_ptr_elem() void = { // D — `arr[i].f` pointer element of a [N]*rec array (LEAQ base, MOVQ // deref to the *rec, then the leaf field load). The element points at a // separately-built struct so the poison rides the proven s1local 3-word // field store, not the broken array-element store. Poison cap=7 (len=3). let p: str = "abc"; p.cap = 7i32; let st: rec; st.f = p; let arr: [3]*rec; arr[1] = &st; let junk: i32 = spoil(); let s: str = arr[1].f; assert(s.cap: i32 == 7); assert(s.len: i32 == 3); assert(junk == 44); };