79 lines
3.5 KiB
Plaintext
79 lines
3.5 KiB
Plaintext
// global_chained_unwrap_test — #16: a single-dot aggregate-field unwrap
|
|
// `g.f = mk()!` whose base is a module-GLOBAL value-struct, or `o.m.f = mk()!`
|
|
// whose base is a CHAINED struct field, dropped payload words (SILENT, both
|
|
// stages, byte-id-BLIND) — still broken after #12 fixed the LOCAL / via-ptr
|
|
// single-dot case. The #12 single-dot arm gated out the global base and its
|
|
// enclosing arm only admits an N_IDENT local base, so a global base fell to
|
|
// the generic single-word store (w1/w2 dropped) and a chained base never
|
|
// reached any field arm at all. The fix routes the destination ADDRESS
|
|
// through the cgplaceaddr spine (global LEAQ root + chained deref+offset) and
|
|
// feeds the SAME {AX=w0,DX=w1,CX=w2} producer-shift materialise the LOCAL arm
|
|
// uses.
|
|
//
|
|
// Both stages emit identically wrong asm pre-fix, so the byte-id gate is BLIND
|
|
// to the drop — these VALUE asserts are the sole tooth. POISON-SEED every dest
|
|
// member to 9 (the struct's init literal) so a dropped w1/w2 reads 9 != the
|
|
// expected value. Reverting either stage's #16 arm reverts the dropped word to
|
|
// 9 and reddens.
|
|
//
|
|
// Coverage = the global value-struct base (2-eightbyte w1 + 3-eightbyte w2
|
|
// teeth) and the chained base both as a value-local root (`o.m.f`) and through
|
|
// a pointer root (`p.m.f` = (*p).m.f). The sub-8-tail-THROUGH-unwrap case is
|
|
// NOT pinnable here for the same reasons as struct_unwrap_test (array success
|
|
// variant checker-rejected; sub-8-tail struct success trips #15's frame-edge
|
|
// class, now closed but covered there).
|
|
//
|
|
// Inline @test fns, not a row-table: the cases vary in LHS PLACE shape
|
|
// (gb.f / gb24.f / o.m.f / p.m.f) and struct width, not in data values over
|
|
// one operation, so a row-array `[](in,exp){}` cannot express them — and that
|
|
// form is itself blocked by cgen #111. Mirrors struct_unwrap_test's #12 pins.
|
|
|
|
package global_chained_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, nb: i64 };
|
|
type box24 = struct { f: s24, nb: i64 };
|
|
type outer = struct { m: box, on: i64 };
|
|
|
|
fn mk2() (s2 | e) = { return s2 { a = 111i64, b = 222i64 }; };
|
|
fn mk24() (s24 | e) = { return s24 { a = 111i64, b = 222i64, c = 333i64 }; };
|
|
|
|
let gb: box = box { f = s2{a=9i64,b=9i64}, nb = 7i64 };
|
|
let gb24: box24 = box24 { f = s24{a=9i64,b=9i64,c=9i64}, nb = 7i64 };
|
|
|
|
@test fn global_dot() void = { // g.f = mk()! — module-global value base
|
|
gb.f = mk2()!;
|
|
assert(gb.f.a == 111i64);
|
|
assert(gb.f.b == 222i64); // w1 tooth
|
|
assert(gb.nb == 7i64); // neighbour field intact
|
|
};
|
|
|
|
@test fn global_dot_w2() void = { // 3-eightbyte global, w2 (R8->CX) tooth
|
|
gb24.f = mk24()!;
|
|
assert(gb24.f.a == 111i64);
|
|
assert(gb24.f.b == 222i64);
|
|
assert(gb24.f.c == 333i64); // w2 tooth
|
|
assert(gb24.nb == 7i64);
|
|
};
|
|
|
|
@test fn chained_dot() void = { // o.m.f = mk()! — chained, value-local root
|
|
let o: outer = outer { m = box { f = s2{a=9i64,b=9i64}, nb = 5i64 }, on = 3i64 };
|
|
o.m.f = mk2()!;
|
|
assert(o.m.f.a == 111i64);
|
|
assert(o.m.f.b == 222i64); // w1 tooth
|
|
assert(o.m.nb == 5i64); // neighbour field intact
|
|
assert(o.on == 3i64);
|
|
};
|
|
|
|
@test fn chained_dot_via_ptr() void = { // p.m.f = mk()! — chained, pointer root
|
|
let o: outer = outer { m = box { f = s2{a=9i64,b=9i64}, nb = 5i64 }, on = 3i64 };
|
|
let p: *outer = &o;
|
|
p.m.f = mk2()!;
|
|
assert(o.m.f.a == 111i64);
|
|
assert(o.m.f.b == 222i64); // w1 tooth
|
|
assert(o.m.nb == 5i64);
|
|
assert(o.on == 3i64);
|
|
};
|