Files
ww/test/lang/local_zeroinit_test.ww
Hojun-Cho 1a57de6ffe test/lang: absorb retired-carrier coverage
local_zeroinit_test.ww takes the 840/944 zero-init seam (dirty-frame
prime and probe share one @test because the runtime forks per test);
alias_cgen_b6, alloc_nested_field, array_static_init, and
strarray_static gain the rows their retired wrappers held; the
remaining files re-point reject-row citations at the r788_* and
stage-matrix fixtures.
2026-08-07 23:21:04 +09:00

183 lines
3.4 KiB
Plaintext

// local_zeroinit_test preserves the retired C wrappers' dirty-frame runtime
// seam. Each @test child
// dirties a callee frame and immediately calls a sibling probe whose bare local
// is its first slot. Keeping the calls in one @test matters: the native runner
// forks once per test, so separate dirty and probe tests could receive clean
// pages and mask a missing zero-fill.
package local_zeroinit_test;
type tiny3 = struct { a: u8, b: u8, c: u8 };
// Preserve the two original poison frames. Besides their distinct byte values,
// the 512-byte int frame exercises the larger array cases while the 64-byte u8
// frame is the historical sub-8 aggregate reproducer.
fn dirty_int_frame() int = {
let j: [64]int;
for (let i: int = 0; i < 64; i += 1) {
j[i] = 165;
};
return j[0];
};
fn dirty_byte_frame() void = {
let big: [64]u8;
let i: i32 = 0;
for (i < 64) {
big[i] = 222u8;
i += 1;
};
};
fn probe_int3() i32 = {
let a: [3]int;
return (a[0] + a[1] + a[2]): i32;
};
fn probe_u32x4() i32 = {
let a: [4]u32;
return (a[0] + a[1] + a[2] + a[3]): i32;
};
fn probe_u8x20_int_frame() i32 = {
let b: [20]u8;
let s: i32 = 0;
for (let i: int = 0; i < 20; i += 1) {
s += b[i]: i32;
};
return s;
};
fn probe_int2x2() i32 = {
let m: [2][2]int;
return (m[0][0] + m[0][1] + m[1][0] + m[1][1]): i32;
};
fn probe_initialized_int3() i32 = {
let c: [3]int = [7, 8, 9];
return (c[0] + c[1] + c[2]): i32;
};
@test fn array_int3_zero() void = {
dirty_int_frame();
assert(probe_int3() == 0);
};
@test fn array_u32x4_zero() void = {
dirty_int_frame();
assert(probe_u32x4() == 0);
};
@test fn array_u8x20_zero() void = {
dirty_int_frame();
assert(probe_u8x20_int_frame() == 0);
};
@test fn nested_array_int2x2_zero() void = {
dirty_int_frame();
assert(probe_int2x2() == 0);
};
@test fn initialized_array_control() void = {
dirty_int_frame();
assert(probe_initialized_int3() == 24);
};
fn probe_u8x3() i32 = {
let c: [3]u8;
return (c[0]: i32) + (c[1]: i32) + (c[2]: i32);
};
fn probe_u8x5() i32 = {
let c: [5]u8;
let acc: i32 = 0;
let j: i32 = 0;
for (j < 5) {
acc += c[j]: i32;
j += 1;
};
return acc;
};
fn probe_u8x7() i32 = {
let c: [7]u8;
let acc: i32 = 0;
let j: i32 = 0;
for (j < 7) {
acc += c[j]: i32;
j += 1;
};
return acc;
};
fn probe_tiny3() i32 = {
let s: tiny3;
return (s.a: i32) + (s.b: i32) + (s.c: i32);
};
fn probe_scalar_i32() i32 = {
let x: i32;
return x;
};
fn probe_u8x20_byte_frame() i32 = {
let c: [20]u8;
let acc: i32 = 0;
let j: i32 = 0;
for (j < 20) {
acc += c[j]: i32;
j += 1;
};
return acc;
};
fn probe_str_len() i32 = {
let empty: str;
return empty.len;
};
fn probe_slice_len() i32 = {
let xs: []i32;
return xs.len;
};
@test fn sub8_array_u8x3_zero() void = {
dirty_byte_frame();
assert(probe_u8x3() == 0);
};
@test fn sub8_array_u8x5_zero() void = {
dirty_byte_frame();
assert(probe_u8x5() == 0);
};
@test fn sub8_array_u8x7_zero() void = {
dirty_byte_frame();
assert(probe_u8x7() == 0);
};
@test fn sub8_struct_u8x3_zero() void = {
dirty_byte_frame();
assert(probe_tiny3() == 0);
};
@test fn scalar_i32_control() void = {
dirty_byte_frame();
assert(probe_scalar_i32() == 0);
};
@test fn array_u8x20_control() void = {
dirty_byte_frame();
assert(probe_u8x20_byte_frame() == 0);
};
@test fn str_header_control() void = {
dirty_byte_frame();
assert(probe_str_len() == 0);
};
@test fn slice_header_control() void = {
dirty_byte_frame();
assert(probe_slice_len() == 0);
};