Migrate the slice/str-header core of drew's Family 1 from bespoke build+run C twins to test/lang @test, retiring each now-redundant twin in the same commit. Runtime coverage MOVES from $(TESTS) to test-lang (T1 runs+asserts via `ww test`) + test-lang-byteid (T2 keeps cs==ww .s byte-id); coverage is preserved, the $(TESTS) headline drops 6 (440->434). All asserts are primitive int/u8/bool comparisons (no fmt/strconv in the assert path); the slice-store families poison the slot (cap!=len) and read it back so a dropped data word FAILS. 928_str_abi_run.c -> str_abi_test.ww (str 24B ABI: .len/.cap across literal/arg/return/field/tuple/deref/index/tagged) 941_slice_store_cap_run.c -> slice_store_cap_test.ww (slice value store through indexed/field/chained lhs writes full 24B header; cap==8) 942_subslice_cap_run.c -> subslice_cap_test.ww (sub-slice cap = base_cap-lo; array/slice/str/append-no-realloc/hi-default) 943_subslice_ptresz_run.c -> subslice_ptresz_test.ww (sub-slice ptr advances lo*esz bytes; esz 2/4/8, let + call-arg) 944_deref_slice_store_run.c-> deref_slice_store_test.ww(*p=sliceval whole-deref store writes 24B header; cap==8) 949_f6_header_run.c -> f6_header_test.ww (str/slice header partial load/store; .cap/.len after clobber) Bump LANGBYTEID_EXPECTED_MIN 16->22 to ratchet the new corpus floor.
85 lines
2.7 KiB
Plaintext
85 lines
2.7 KiB
Plaintext
// subslice_ptresz_test — a sub-slice `base[lo:hi]` must advance its DATA
|
|
// pointer by lo*esz (BYTES), not by lo (element COUNT), migrated from
|
|
// test/wcc/943_subslice_ptresz_run.c (project #76). The rt invariant is
|
|
// membsz-unit pointer arithmetic (ref/hare/rt/ensure.ha:30). For esz==1 (u8/str)
|
|
// lo*1 == lo, so those paths are unaffected; the bug only bites esz>1.
|
|
//
|
|
// Before the fix BOTH stages emitted ptr = base + lo (unscaled), so the first
|
|
// element was read at byte offset `lo` into the base — garbage straddling
|
|
// base[0]/base[1] for any esz>1. Each row picks values where the unscaled read
|
|
// cannot alias the scaled one, so a stale `+lo` stage returns garbage, not the
|
|
// expected element. Exercises esz 2/4/8 over array + slice bases via the
|
|
// let-form (value path) and the call-arg fast path.
|
|
|
|
package subslice_ptresz_test;
|
|
|
|
fn e0(s: []i32) i32 = { return s[0]; };
|
|
fn e1(s: []i32) i32 = { return s[1]; };
|
|
fn f0(s: []i64) i64 = { return s[0]; };
|
|
fn f1(s: []i64) i64 = { return s[1]; };
|
|
|
|
@test fn subslice_esz4_array_let() void = {
|
|
// A — esz=4 array base, let-form (value path). s[0]=a[2]=1002.
|
|
let a: [8]i32;
|
|
let i: i32 = 0;
|
|
for (i < 8) { a[i] = 1000 + i; i += 1; };
|
|
let s: []i32 = a[2:5];
|
|
assert(s.len: i32 == 3);
|
|
assert(s[0] == 1002);
|
|
assert(s[1] == 1003);
|
|
};
|
|
|
|
@test fn subslice_esz2_array_let() void = {
|
|
// B — esz=2 array base, let-form. s[0]=a[3]=103.
|
|
let a: [8]i16;
|
|
let i: i32 = 0;
|
|
for (i < 8) { a[i] = (100 + i): i16; i += 1; };
|
|
let s: []i16 = a[3:6];
|
|
assert(s.len: i32 == 3);
|
|
assert(s[0]: i32 == 103);
|
|
assert(s[1]: i32 == 104);
|
|
};
|
|
|
|
@test fn subslice_esz8_array_let() void = {
|
|
// C — esz=8 array base, let-form. s[0]=a[1]=5001.
|
|
let a: [8]i64;
|
|
let i: i32 = 0;
|
|
for (i < 8) { a[i] = (5000 + i): i64; i += 1; };
|
|
let s: []i64 = a[1:4];
|
|
assert(s.len: i32 == 3);
|
|
assert(s[0]: i32 == 5001);
|
|
assert(s[1]: i32 == 5002);
|
|
};
|
|
|
|
@test fn subslice_esz4_slice_let() void = {
|
|
// D — esz=4 slice base, let-form. base ptr from header + lo*esz.
|
|
// s[0]=a[2]=1002.
|
|
let a: [8]i32;
|
|
let i: i32 = 0;
|
|
for (i < 8) { a[i] = 1000 + i; i += 1; };
|
|
let p: []i32; p.ptr = &a[0]; p.len = 6; p.cap = 8;
|
|
let s: []i32 = p[2:5];
|
|
assert(s.len: i32 == 3);
|
|
assert(s[0] == 1002);
|
|
assert(s[1] == 1003);
|
|
};
|
|
|
|
@test fn subslice_esz4_call_arg() void = {
|
|
// E — esz=4 call-arg (the pushargsrev twin). The fn reads s[0]/s[1] of
|
|
// `a[3:6]` -> 1003 / 1004.
|
|
let a: [8]i32;
|
|
let i: i32 = 0;
|
|
for (i < 8) { a[i] = 1000 + i; i += 1; };
|
|
assert(e0(a[3:6]) == 1003);
|
|
assert(e1(a[3:6]) == 1004);
|
|
};
|
|
|
|
@test fn subslice_esz8_call_arg() void = {
|
|
// F — esz=8 call-arg. The fns read s[0]/s[1] of `a[2:5]` -> 5002 / 5003.
|
|
let a: [8]i64;
|
|
let i: i32 = 0;
|
|
for (i < 8) { a[i] = (5000 + i): i64; i += 1; };
|
|
assert(f0(a[2:5]): i32 == 5002);
|
|
assert(f1(a[2:5]): i32 == 5003);
|
|
};
|