Files
ww/test/lang/slice_global_arg_runonly_test.ww
Hojun-Cho 132ea4ee60 test: migrate Fam13 misc checker/coercion value tests to @test (#5-C6)
Final fold-2 chunk. The 12 Fam13 single-file value drivers move from
test/wcc/*_run.c into in-language @test row-tables under test/lang/:

- value rows -> test/lang/*_test.ww (12 files)
- reject rows -> runww //ww:error carriers (13, dual-stage non-vacuous)
- nullable abort rows -> runww //ww:run-exit 1 carriers (3)
- 953_globalslice_arg -> _runonly (cs!=ww checker divergence, #28)
- 788 value_not_type_neg + 953_arrlit_slice reject_assign kept as slim
  rc-only .c pins (divergent-diag dual-reject, mutation-gated); 788 #29

Coverage parity verified row-by-row vs each retired driver; advisor-
ratified carve taxonomy; two-round reviewed. Floor ratchet follows.
2026-06-24 22:59:32 +09:00

53 lines
1.6 KiB
Plaintext

// slice_global_arg_runonly_test — #148 (D2): a module-global slice passed BY
// VALUE as a slice arg must arrive with a real header, not garbage. Migrated
// from test/wcc/953_globalslice_arg_run.c.
//
// _runonly: CSTAGE-ONLY. wwstage's checker rejects a module-level `const []T`
// global ("let: not assignable", filed task #28), so this file does not compile
// under w6c_ww and is excluded from the T2 byte-id corpus. test-lang runs it
// through the cstage `ww test` only.
//
// Pre-fix the slice-ident call-arg fast path emitted BP-relative pushes for a
// global (localfind→0), reading saved-BP/RIP garbage instead of the global's
// header at name(SB). The fix mirrors the N_SLICE arm's isglobal dispatch. The
// callee reads .len AND a byte, so a wrong header is observable; u32_global
// pins the path is element-width-agnostic; direct_read + local_arg lock the
// in-place read and the off!=0 local arm against regression.
package slice_global_arg_runonly_test;
const dotdot: []u8 = ['.', '.'];
const dot: []u8 = ['.'];
const g: []u32 = [7u32, 8u32, 9u32];
const d: []u32 = [11u32, 22u32];
fn seen_u8(bs: []u8) i32 = {
return bs.len: i32 * 1000 + bs[0]: i32;
};
fn seen_u32(xs: []u32) i32 = {
return xs.len: i32 * 100 + xs[0]: i32 + xs[2]: i32;
};
@test fn u8_dotdot() void = {
assert(seen_u8(dotdot) == 2046);
};
@test fn u8_dot() void = {
assert(seen_u8(dot) == 1046);
};
@test fn u32_global() void = {
assert(seen_u32(g) == 316);
};
@test fn direct_read() void = {
assert(d.len: i32 * 100 + d[0]: i32 + d[1]: i32 == 233);
};
@test fn u8_local_arg() void = {
let a: [2]u8 = ['.', '.'];
let s: []u8 = a[0:2];
assert(seen_u8(s) == 2046);
};