949_dotfield_compound + 949_idxfield_compound are one bug class (#133-lineage compound-assign load-op-store on field lvalues; #34/#33, #263 carve-out) sharing the combine + hard-error path, so the two C carriers fuse into one commit: 26 value rows -> test/lang @test row-tables (primitive-only asserts), 8 reject rows -> runww //ww:error dual-stage carriers. byteid floor 50->52.
117 lines
3.3 KiB
Plaintext
117 lines
3.3 KiB
Plaintext
// idxfield_compound_test — indexed-element field compound-assign (#33, #263
|
|
// both stages), migrated from test/wcc/949_idxfield_compound_run.c. A compound
|
|
// assign on an indexed-element FIELD lvalue (`arr[i].field OP= v`) must do a
|
|
// real LOAD-OP-STORE for ALL ten integer ops, not silently no-op the four the
|
|
// arm never wired (SLASHEQ/PERCENTEQ/LSHIFTEQ/RSHIFTEQ loaded the old value
|
|
// into AX, fired no combine, and stored AX back — a silent no-op in BOTH
|
|
// stages, gate-blind/byte-identical). Every row init-poisons xs[0].f with a
|
|
// value != the expected result, runs the op, reads the field back, and asserts
|
|
// a sibling slot (xs[0].g or xs[1].f) 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 i32/i64/u32 fields and a via-ptr element ([N]*S); the
|
|
// plain-assign control pins the ASSIGN path the fix must leave unchanged. T2
|
|
// keeps cs==ww.
|
|
|
|
package idxfield_compound_test;
|
|
|
|
type S32 = struct { f: i32, g: i32 };
|
|
type S64 = struct { f: i64, g: i64 };
|
|
type Su32 = struct { f: u32, g: u32 };
|
|
|
|
@test fn fld_i32_pluseq() void = {
|
|
let xs: [2]S32 = [S32{f=100, g=0}, S32{f=0, g=0}];
|
|
xs[0].f += 50;
|
|
assert(xs[0].f == 150);
|
|
assert(xs[0].g == 0);
|
|
assert(xs[1].f == 0);
|
|
};
|
|
|
|
@test fn fld_i64_stareq() void = {
|
|
let xs: [2]S64 = [S64{f=6i64, g=0i64}, S64{f=0i64, g=0i64}];
|
|
xs[0].f *= 7i64;
|
|
assert(xs[0].f == 42i64);
|
|
assert(xs[0].g == 0i64);
|
|
assert(xs[1].f == 0i64);
|
|
};
|
|
|
|
@test fn fld_i32_slasheq() void = {
|
|
let xs: [2]S32 = [S32{f=100, g=0}, S32{f=0, g=0}];
|
|
xs[0].f /= 4;
|
|
assert(xs[0].f == 25);
|
|
assert(xs[0].g == 0);
|
|
assert(xs[1].f == 0);
|
|
};
|
|
|
|
@test fn fld_i32_slasheq_neg() void = {
|
|
let xs: [2]S32 = [S32{f=-17, g=0}, S32{f=0, g=0}];
|
|
xs[0].f /= 4;
|
|
assert(xs[0].f == -4);
|
|
assert(xs[0].g == 0);
|
|
assert(xs[1].f == 0);
|
|
};
|
|
|
|
@test fn fld_u32_slasheq() void = {
|
|
let xs: [2]Su32 = [Su32{f=100u32, g=0u32}, Su32{f=0u32, g=0u32}];
|
|
xs[0].f /= 4u32;
|
|
assert(xs[0].f == 25u32);
|
|
assert(xs[0].g == 0u32);
|
|
assert(xs[1].f == 0u32);
|
|
};
|
|
|
|
@test fn fld_i32_percenteq() void = {
|
|
let xs: [2]S32 = [S32{f=17, g=0}, S32{f=0, g=0}];
|
|
xs[0].f %= 5;
|
|
assert(xs[0].f == 2);
|
|
assert(xs[0].g == 0);
|
|
assert(xs[1].f == 0);
|
|
};
|
|
|
|
@test fn fld_u32_percenteq() void = {
|
|
let xs: [2]Su32 = [Su32{f=100u32, g=0u32}, Su32{f=0u32, g=0u32}];
|
|
xs[0].f %= 7u32;
|
|
assert(xs[0].f == 2u32);
|
|
assert(xs[0].g == 0u32);
|
|
assert(xs[1].f == 0u32);
|
|
};
|
|
|
|
@test fn fld_i32_lshifteq() void = {
|
|
let xs: [2]S32 = [S32{f=3, g=0}, S32{f=0, g=0}];
|
|
xs[0].f <<= 4;
|
|
assert(xs[0].f == 48);
|
|
assert(xs[0].g == 0);
|
|
assert(xs[1].f == 0);
|
|
};
|
|
|
|
@test fn fld_u32_rshifteq() void = {
|
|
let xs: [2]Su32 = [Su32{f=200u32, g=0u32}, Su32{f=0u32, g=0u32}];
|
|
xs[0].f >>= 2u32;
|
|
assert(xs[0].f == 50u32);
|
|
assert(xs[0].g == 0u32);
|
|
assert(xs[1].f == 0u32);
|
|
};
|
|
|
|
@test fn fld_i32_rshifteq_neg() void = {
|
|
let xs: [2]S32 = [S32{f=-16, g=0}, S32{f=0, g=0}];
|
|
xs[0].f >>= 2;
|
|
assert(xs[0].f == -4);
|
|
assert(xs[0].g == 0);
|
|
assert(xs[1].f == 0);
|
|
};
|
|
|
|
@test fn fld_viaptr_pluseq() void = {
|
|
let a: S32 = S32{f=10, g=0};
|
|
let xs: [2]*S32 = [&a, &a];
|
|
xs[0].f += 5;
|
|
assert(a.f == 15);
|
|
assert(a.g == 0);
|
|
};
|
|
|
|
@test fn fld_plain_assign_ctrl() void = {
|
|
let xs: [2]S32 = [S32{f=1, g=0}, S32{f=0, g=0}];
|
|
xs[0].f = 99;
|
|
assert(xs[0].f == 99);
|
|
assert(xs[0].g == 0);
|
|
assert(xs[1].f == 0);
|
|
};
|