Every section banner dies (103 -> 0) across test/lang, the observer suites, the C carriers, and the five comment-heavy corpus fixtures; banner provenance (#N cites, carrier numbers, repair-cluster labels) folded into headers or adjacent WHY comments. Narration deleted; row provenance, ref cites, divergence pins, and layout contracts kept (fwd-ref decl-order guards and bootstrap-gate corpus rationale restored where the sweep over-cut). Comment-only proven: all 3742 wwbuild workdir .s byte-identical before/after; test-commit and test-byteid (161 lang + 1399 data, 0 pinned-divergent) green.
78 lines
3.5 KiB
Plaintext
78 lines
3.5 KiB
Plaintext
// #12: an aggregate (struct) success-variant unwrap
|
|
// `(S|e)!` / `r?` dropped payload words (SILENT, both stages, byte-id-BLIND).
|
|
// A struct success variant rides the in-cap {AX=w0,DX=w1,CX=w2} GP ABI — a
|
|
// DIFFERENT shuffle from #6's str/slice {ptr,len,cap} header. Two layers:
|
|
// L1 PRODUCER (cgtrytaggedshift / cgen.c N_TRYPROP+N_TRYUNW): a struct/array
|
|
// success variant matched no arm and fell to the bare `MOVQ DX,AX`,
|
|
// materialising only w0 — w1/w2 (in CX/R8) dropped.
|
|
// L2 CONSUMER (the aggregate-STORE arms): gated rhs.kind==N_CALL and stored
|
|
// one word for an N_TRYUNW/N_TRYPROP rhs — admitting the unwrap kinds
|
|
// reuses the #10-correct scratch materialise.
|
|
// Both layers are silent both-stage, so the byte-id gate is BLIND to the drop —
|
|
// these VALUE asserts are the sole tooth. Reverting either stage's L2 relax (or
|
|
// the shared L1 producer) reverts the dropped word to the poison sentinel 9 and
|
|
// reddens. POISON-SEED every dest member to 9 so a dropped w1/w2 reads 9 != the
|
|
// expected nonzero value (a fresh-frame 0 would also mismatch, but 9 is robust).
|
|
//
|
|
// Coverage = the three SILENT store shapes (arr-elem C2c, single-dot field
|
|
// direct + via-ptr, indexed-field #11) for a clean 2-eightbyte s2 (w1 tooth)
|
|
// plus a 3-eightbyte s24 (w2 tooth — exercises the producer's R8->CX shift).
|
|
// The sub-8-tail-THROUGH-unwrap case (#10's tail) is NOT pinnable: an ARRAY
|
|
// success variant is checker-rejected (`([7]i16|e)`, task #5/#60) and a sub-8-
|
|
// tail STRUCT success variant trips a SEPARATE pre-existing bug — the union-
|
|
// return struct-lit fill overruns saved BP when the variant ends at the frame
|
|
// edge (g's MOVQ writes past the 14B struct into [BP]); filed for the lead.
|
|
|
|
package struct_unwrap_test;
|
|
|
|
type e = !i32;
|
|
type s2 = struct { a: i64, b: i64 }; // 2 eightbytes: w0=a, w1=b
|
|
type s24 = struct { a: i64, b: i64, c: i64 }; // 3 eightbytes: w0,w1,w2
|
|
type box = struct { f: s2, g: i64 };
|
|
|
|
fn mk2() (s2 | e) = { return s2 { a = 111i64, b = 222i64 }; };
|
|
fn mk24() (s24 | e) = { return s24 { a = 111i64, b = 222i64, c = 333i64 }; };
|
|
|
|
@test fn arr_elem() void = { // L2 site: C2c whole-element arr[i]=mk()!
|
|
let arr: [2]s2;
|
|
arr[1].a = 9i64; arr[1].b = 9i64; // poison: w1 sentinel 9 != 222
|
|
arr[1] = mk2()!;
|
|
assert(arr[1].a == 111i64);
|
|
assert(arr[1].b == 222i64); // w1 — the dropped-word tooth
|
|
};
|
|
|
|
@test fn arr_elem_w2() void = { // C2c, 3 eightbytes — w2 (R8->CX) tooth
|
|
let arr: [2]s24;
|
|
arr[1].a = 9i64; arr[1].b = 9i64; arr[1].c = 9i64;
|
|
arr[1] = mk24()!;
|
|
assert(arr[1].a == 111i64);
|
|
assert(arr[1].b == 222i64);
|
|
assert(arr[1].c == 333i64); // w2 tooth (>16B producer shift)
|
|
};
|
|
|
|
@test fn field_direct() void = { // L2 site: single-dot direct b.f=mk()!
|
|
let b: box = box { f = s2{a=9i64,b=9i64}, g = 7i64 };
|
|
b.f = mk2()!;
|
|
assert(b.f.a == 111i64);
|
|
assert(b.f.b == 222i64); // w1 tooth
|
|
assert(b.g == 7i64); // neighbour field intact
|
|
};
|
|
|
|
@test fn field_via_ptr() void = { // L2 site: single-dot via *struct p.f=mk()!
|
|
let b: box = box { f = s2{a=9i64,b=9i64}, g = 7i64 };
|
|
let p: *box = &b;
|
|
p.f = mk2()!;
|
|
assert(b.f.a == 111i64);
|
|
assert(b.f.b == 222i64); // w1 tooth
|
|
assert(b.g == 7i64);
|
|
};
|
|
|
|
@test fn field_of_indexed() void = { // L2 site: #11 indexed-field arr[i].f=mk()!
|
|
let arr: [2]box;
|
|
arr[1].g = 5i64; arr[1].f.a = 9i64; arr[1].f.b = 9i64;
|
|
arr[1].f = mk2()!;
|
|
assert(arr[1].f.a == 111i64);
|
|
assert(arr[1].f.b == 222i64); // w1 tooth
|
|
assert(arr[1].g == 5i64); // neighbour field intact
|
|
};
|