// dotfield_compound_test — single-dot field compound-assign (#34, #263 both // stages), migrated from test/wcc/949_dotfield_compound_run.c. A compound // assign on a single-dot field lvalue (`s.f OP= v`, `p.f OP= v`, `g.f OP= v`, // `sl.len OP= v`) must do a real LOAD-OP-STORE for ALL ten integer ops, not // silently demote a non-+=/-= op to a plain `s.f = rhs` (the prior bug: *= /= // %= &= |= ^= <<= >>= left old-in-BX/rhs-in-AX then stored AX, so `s.f *= 3` // compiled to `s.f = 3`, gate-blind/byte-identical). Every row init-poisons // the field with a value != the expected result, runs the op, reads the field // back, and asserts the sibling field `g` (or the slice `.cap`) is UNTOUCHED to // catch an over-wide / wrong-offset store. PRIMITIVE-only asserts (no // fmt/strconv) so a co-miscompile in the assert path cannot mask the bug. The // matrix covers + * / % << >> across int/i32/u32 fields, a via-ptr base, a // global struct field, and the str/slice `.len` pseudo-field; the plain-assign // control pins the ASSIGN path the fix must leave unchanged. T2 keeps cs==ww. package dotfield_compound_test; type Sii = struct { f: int, g: int }; type S32 = struct { f: i32, g: i32 }; type Su32 = struct { f: u32, g: u32 }; let gs: Sii = Sii{f=20, g=0}; fn bump(p: *Sii) void = { p.f *= 3; }; @test fn dotfld_pluseq_ctrl() void = { let s: Sii = Sii{f=10, g=0}; s.f += 5; assert(s.f == 15); assert(s.g == 0); }; @test fn dotfld_stareq() void = { let s: Sii = Sii{f=5, g=0}; s.f *= 3; assert(s.f == 15); assert(s.g == 0); }; @test fn dotfld_slasheq_signed() void = { let s: Sii = Sii{f=100, g=0}; s.f /= 4; assert(s.f == 25); assert(s.g == 0); }; @test fn dotfld_slasheq_neg() void = { let s: S32 = S32{f=-17, g=0}; s.f /= 4; assert(s.f == -4); assert(s.g == 0); }; @test fn dotfld_slasheq_unsigned() void = { let s: Su32 = Su32{f=100u32, g=0u32}; s.f /= 4u32; assert(s.f == 25u32); assert(s.g == 0u32); }; @test fn dotfld_percenteq() void = { let s: Sii = Sii{f=17, g=0}; s.f %= 5; assert(s.f == 2); assert(s.g == 0); }; @test fn dotfld_lshifteq() void = { let s: Sii = Sii{f=3, g=0}; s.f <<= 4; assert(s.f == 48); assert(s.g == 0); }; @test fn dotfld_rshifteq_neg() void = { let s: S32 = S32{f=-16, g=0}; s.f >>= 2; assert(s.f == -4); assert(s.g == 0); }; @test fn dotfld_rshifteq_unsigned() void = { let s: Su32 = Su32{f=200u32, g=0u32}; s.f >>= 2u32; assert(s.f == 50u32); assert(s.g == 0u32); }; @test fn dotfld_viaptr_stareq() void = { let a: Sii = Sii{f=4, g=0}; bump(&a); assert(a.f == 12); assert(a.g == 0); }; @test fn dotfld_global_slasheq() void = { gs.f /= 4; assert(gs.f == 5); assert(gs.g == 0); }; @test fn dotfld_pseudo_len_minuseq() void = { let buf: [8]u8 = [1u8,2u8,3u8,4u8,5u8,6u8,7u8,8u8]; let sl: []u8 = buf[0:8]; sl.len -= 3; assert(sl.len == 5); assert(sl.cap == 8); }; @test fn dotfld_pseudo_len_stareq() void = { let buf: [8]u8 = [1u8,2u8,3u8,4u8,5u8,6u8,7u8,8u8]; let sl: []u8 = buf[0:4]; sl.len *= 3; assert(sl.len == 12); assert(sl.cap == 8); }; @test fn dotfld_plain_assign_ctrl() void = { let s: Sii = Sii{f=1, g=0}; s.f = 99; assert(s.f == 99); assert(s.g == 0); };