test: migrate Fam10 alias value tests to @test, carve divergences to pins (#5-C3)

fold-2 chunk C3 (drew's Fam8-13 plan): 8 alias value-row C drivers, 205 rows
re-homed with zero loss -- 177 value -> 8 test/lang/alias_*_test.ww @test
row-tables; 16 reject -> runww //ww:error carriers (both stages reject);
3 cs!=ww value rows -> 2 *_runonly_test.ww (T1, byte-id-excluded, #60/#81);
9 irreducible asymmetric rows -> slim C pins, each ticket-cited and
mutation-proven non-vacuous:
  - accept amplen1/2,ampcap2: cs runs / ww rejects 'unsupported address-of
    shape' (#96)
  - cgen_b5 g73_heapfill: cs!=ww .s + ww link-fails on self-contained alloc;
    compile-smoke pin (#24)
  - cgen_b6 fsarg2_bound: both reject, different msgs, each vs the correct
    stage (#271/#165 cs vs #272/#276/#277 ww)
  - emit_b7 slc/slcstr/slctag _2lvl + slc_plain_ctl: slice-literal static-init
    divergence (#120/#29-kin, ken-d2-oracle)
4 fully-migrated drivers deleted, 4 slimmed-in-place to hold only the
irreducible pins. LANGBYTEID floor 74->82 (8 new byte-id @test files); test
count 388->384 (4 deleted; 4 slimmed kept). do-not-auto-batch files not in
Fam10.
This commit is contained in:
2026-06-24 02:45:09 +09:00
parent 07b3c74ab0
commit 3ee1906497
35 changed files with 2627 additions and 4614 deletions

View File

@@ -0,0 +1,20 @@
// alias_accept_runonly_test — the cs≠ww .s carve-out split from
// alias_accept_test (#5-C3, #7f/#254 value-only runonly home). A bare
// (anonymous-let) struct widened into a 2-level alias variant: the asm
// diverges on 3 pre-existing cglet zero-fill lines (cs XORQ+2 stores, ww none
// — task #81 class), runtime-correct on BOTH stages, ORTHOGONAL to the variant
// tag under test. The acceptance + correct-tag behavior stays pinned on the
// cstage run (T1); the file is *_runonly so the test-lang-byteid (T2) corpus
// excludes it. Flip back into alias_accept_test when the #81 zero-fill
// divergence closes. Migrated from test/wcc/944_alias_accept_run.c.
package alias_accept_runonly_test;
type sa = struct { a: i64, };
type sb = sa;
@test fn v2_struct2() void = {
let s: struct { a: i64, } = sa{a=7};
let v: (void | sb) = s;
assert(v is sb);
};

View File

@@ -0,0 +1,812 @@
// alias_accept_test — #5 alias arc F1: the transitive TY_NAMED chase. cstage
// single-peeled the alias at promotion/cond/assign/index/field/arg/union/cast
// consumers, so a 2+-level alias (or one alias over a named aggregate) left the
// type TY_NAMED and fell to a scalar/word0-only/pointer tail — runtime-wrong or
// byte-diverging vs wwstage (which already chased). Each @test pins one consumer
// shape, asserting the value the C row checked so a re-narrowing can't hide.
// Migrated from test/wcc/944_alias_accept_run.c (#5-C3).
package alias_accept_test;
// binop_alias_base
type bab_myint = int;
// binop_2level
type b2_myint = int;
type b2_myint2 = b2_myint;
type b2_myu = u32;
// ret_through_2level
type rt_myint = int;
type rt_myint2 = rt_myint;
// assign_alias_alias
type aa_k1 = int;
type aa_k2 = int;
// cond_* family (alias-of-bool)
type cond_myb = bool;
// dot_2level (alias declared before base — forward ref under test)
type dot_a3 = dot_b3;
type dot_b3 = dot_c3;
type dot_c3 = struct { x: size, y: size, z: size };
// deref_alias_ptr
type dp_pi = *int;
type dp_pi2 = dp_pi;
// slicefield_store_2lvl
type sfs_sl = []int;
type sfs_sl2 = sfs_sl;
type sfs_box = struct { s: sfs_sl2, n: int };
// slicefield_range_2lvl
type sfr_sl = []int;
type sfr_sl2 = sfr_sl;
type sfr_box = struct { s: sfr_sl2, n: int };
// strfield_store_2lvl
type sfst_s1t = str;
type sfst_s2t = sfst_s1t;
type sfst_box = struct { s: sfst_s2t, n: int };
// slicefield_structlit_2lvl
type sfsl_sl = []int;
type sfsl_sl2 = sfsl_sl;
type sfsl_box = struct { s: sfsl_sl2, n: int };
// slicefield_viaptr_2lvl
type sfv_sl = []int;
type sfv_sl2 = sfv_sl;
type sfv_box = struct { s: sfv_sl2, n: int };
// slicefield_chainstore_2lvl
type sfc_sl = []int;
type sfc_sl2 = sfc_sl;
type sfc_inner = struct { s: sfc_sl2 };
type sfc_outer = struct { i: sfc_inner };
// slicefield_ptrchain_2lvl
type sfp_sl = []int;
type sfp_sl2 = sfp_sl;
type sfp_inner = struct { s: sfp_sl2, n: int };
type sfp_outer = struct { pi: *sfp_inner };
// slicefield_chainread_2lvl
type sfcr_sl = []int;
type sfcr_sl2 = sfcr_sl;
type sfcr_inner = struct { s: sfcr_sl2 };
type sfcr_outer = struct { i: sfcr_inner };
// slicefield_ptrread_2lvl
type sfpr_sl = []int;
type sfpr_sl2 = sfpr_sl;
type sfpr_box = struct { s: sfpr_sl2, n: int };
// slicefield_wholeread_2lvl
type sfw_sl = []int;
type sfw_sl2 = sfw_sl;
type sfw_box = struct { s: sfw_sl2, n: int };
// slicefield_idx_tripwire_73
type sfi_sl = []int;
type sfi_sl2 = sfi_sl;
type sfi_box = struct { s: sfi_sl2, n: int };
// idx_2level
type idx_arr = [4]int;
type idx_arr2 = idx_arr;
// slice_2level
type sl2_sl = []int;
type sl2_sl2 = sl2_sl;
// range_2level
type rng_arr = [4]int;
type rng_arr2 = rng_arr;
// slice_of_alias_arg
type soa_arr = [4]int;
type soa_arr2 = soa_arr;
// float_alias_param_kenv3 (alias before base — forward ref)
type fak_fa = fak_fb;
type fak_fb = f64;
// float_alias_param
type fap_f1t = f64;
type fap_f2t = fap_f1t;
// str_alias_2level
type sa2_s1t = str;
type sa2_s2t = sa2_s1t;
// slice_alias_param
type slp_b1 = []int;
type slp_b2 = slp_b1;
// arg_2level_fwdref (alias before base — forward ref)
type afr_ali = afr_base;
type afr_base = struct { a: size, b: size, c: size };
// arg_2level_litinit
type ali_st = struct { a: size, b: size, c: size };
type ali_row = ali_st;
// arg_2level_5word
type a5_big = struct { a: size, b: size, c: size, d: size, e: size };
type a5_big2 = a5_big;
// arg_2level_floatclass
type afc_fs = struct { x: f64, n: size };
type afc_fs2 = afc_fs;
// arg_base_control
type abc_base = struct { a: size, b: size, c: size };
// union_store_norm
type usn_base = struct { a: size, b: size };
type usn_ali = usn_base;
// union_store_fwd (alias before base — forward ref)
type usf_ali = usf_base;
type usf_base = struct { a: size, b: size };
// union_store_3word
type us3_base = struct { a: size, b: size, c: size };
type us3_ali = us3_base;
// union_push_arg
type upa_base = struct { a: size, b: size };
type upa_ali = upa_base;
// union_store_base_ctl
type usbc_base = struct { a: size, b: size, c: size };
// union_slit_base_ctl
type uslbc_base = struct { a: size, b: size };
// union_slit_alias
type usla_base = struct { a: size, b: size };
type usla_ali = usla_base;
// union_slit_alias2
type usl2_base = struct { a: size, b: size };
type usl2_ali = usl2_base;
type usl2_ali2 = usl2_ali;
// union_slit_order (alias before base — forward ref)
type uslo_ali = uslo_base;
type uslo_base = struct { a: size, b: size };
// castprim_3lvl_base
type cp3_s1 = struct { f: u32 };
type cp3_s2 = cp3_s1;
type cp3_s3 = cp3_s2;
// castprim_ptr2lvl_base
type cpp_s1 = struct { f: u32 };
type cpp_s2 = cpp_s1;
// castprim_2lvl_base_ctl
type cp2_s1 = struct { f: u32 };
type cp2_s2 = cp2_s1;
// untyped_tagdst_2lvl_hold
type utd_r1 = (void | size);
type utd_r2 = utd_r1;
// untyped_str2lvl_ctl
type usc_sa1 = str;
type usc_sa2 = usc_sa1;
// untyped_int2lvl_ctl
type uic_ia1 = i64;
type uic_ia2 = uic_ia1;
// untyped_bool1lvl_ctl
type ub1_ba1 = bool;
// untyped_bool2lvl_bound90
type ub2_bb1 = bool;
type ub2_bb2 = ub2_bb1;
// v2_ctrl
type v2c_pc = *i64;
// v2_alias2
type v2a_pa = *i64;
type v2a_pb = v2a_pa;
// sp_alias1
type sp1_inner = (i64 | str);
type sp1_outer = (...sp1_inner | void);
// sp_alias2
type sp2_inner = (i64 | str);
type sp2_inner2 = sp2_inner;
type sp2_outer = (...sp2_inner2 | void);
// rangevar_alias2
type rva_slk = []int;
// nested_alias_field_norm
type nfn_fa = nfn_inner;
type nfn_inner = struct { a: size, b: size };
type nfn_outer = struct { x: nfn_fa, y: nfn_fa };
// nested_alias_field_fwd (outer before fa before inner — forward ref)
type nff_outer = struct { x: nff_fa, y: nff_fa };
type nff_fa = nff_inner;
type nff_inner = struct { a: size, b: size };
fn rt_dbl(x: rt_myint2) int = {
return x * 2;
};
fn cond_pick(b: cond_myb) i32 = {
if (b) { return 0; };
return 1;
};
fn sfcr_noise(x: int) int = {
return x * 7 + 3;
};
fn sfpr_noise(x: int) int = {
return x * 7 + 3;
};
fn sfw_noise(x: int) int = {
return x * 7 + 3;
};
fn soa_sum(s: []int) int = {
let t: int = 0;
for (let x .. s) { t = t + x; };
return t;
};
fn fak_take(x: fak_fa) f64 = {
return x * 2.0;
};
fn fap_half(x: fap_f2t) f64 = {
return x / 2.0;
};
fn sa2_taillen(s: sa2_s2t) int = {
return (s.len: int);
};
fn slp_first(s: slp_b2) int = {
return s[0];
};
fn afr_take(s: afr_ali) size = {
return s.a + s.b + s.c;
};
fn ali_take(s: ali_row) size = {
return s.a + s.b + s.c;
};
fn a5_take(s: a5_big2) size = {
return s.a + s.e;
};
fn afc_take(s: afc_fs2) size = {
if (s.x != 2.5) { return 99; };
return s.n;
};
fn abc_take(s: abc_base) size = {
return s.a + s.b + s.c;
};
fn upa_peek(v: (void | upa_ali)) size = {
match (v) {
case let s: upa_ali => { return s.b; };
case void => { return 0; };
};
};
@test fn binop_alias_base() void = {
let a: bab_myint = 5;
let b: int = 3;
let c = a + b;
assert(c == 8);
let d: bab_myint = 2;
assert(a * d == 10);
assert(!(a < b));
assert(a - b == 2);
};
@test fn binop_2level() void = {
let a: b2_myint2 = 7;
let b: int = 2;
assert(a % b == 1);
let u: b2_myu = 10: u32;
let v: u32 = 3: u32;
assert(u / v == 3: u32);
assert(u + v == 13: u32);
};
@test fn ret_through_2level() void = {
let a: rt_myint2 = 21;
assert(rt_dbl(a) == 42);
};
@test fn assign_alias_alias() void = {
let x: aa_k1 = 5;
let y: aa_k2 = x;
assert(y == 5);
};
// alias-bool at the IF consumer (assert itself rejects alias-bool — that loud
// case is assert_stays_loud, not migrated here).
@test fn cond_if() void = {
let b: cond_myb = true;
let r: int = 1;
if (b) { r = 0; };
assert(r == 0);
};
@test fn cond_for() void = {
let b: cond_myb = true;
let i: int = 0;
for (b) {
i = i + 1;
if (i >= 3) { b = false; };
};
assert(i == 3);
};
@test fn cond_bang() void = {
let b: cond_myb = false;
let n = !b;
let r: int = 0;
if (!n) { r = 1; };
assert(r == 0);
};
@test fn cond_andor() void = {
let b: cond_myb = true;
let c: cond_myb = false;
let r: int = 0;
if (b && !c) { } else { r = 1; };
assert(r == 0);
if (c || b) { } else { r = 2; };
assert(r == 0);
};
@test fn cond_fnparam() void = {
let b: cond_myb = true;
assert(cond_pick(b) == 0);
};
@test fn dot_2level() void = {
assert(size(dot_a3) == 24);
assert(size((void | dot_a3)) == 32);
let v: dot_a3;
v.x = 1; v.y = 2; v.z = 3;
assert(v.x + v.y + v.z == 6);
};
@test fn deref_alias_ptr() void = {
let v: int = 41;
let p: dp_pi2 = &v;
assert(*p == 41);
*p = 7;
assert(v == 7);
};
@test fn slicefield_store_2lvl() void = {
let a: [3]int = [700: int, 800: int, 900: int];
let b: sfs_box;
b.n = 5;
b.s = a[0:3];
assert(b.n == 5);
assert(b.s[0] == 700);
assert(b.s[2] == 900);
assert(b.s.len == 3);
};
@test fn slicefield_range_2lvl() void = {
let a: [3]int = [700: int, 800: int, 900: int];
let b: sfr_box;
b.s = a[0:3];
b.n = 5;
assert(b.s.len == 3);
assert(b.s[2] == 900);
for (let x .. b.s) {
assert(!(x < 700));
};
};
@test fn strfield_store_2lvl() void = {
let b: sfst_box;
b.s = "hello";
b.n = 5;
assert(b.s.len == 5);
};
@test fn slicefield_structlit_2lvl() void = {
let a: [3]int = [700: int, 800: int, 900: int];
let b: sfsl_box = sfsl_box { s = a[0:3], n = 5: int };
assert(b.n == 5);
assert(b.s.len == 3);
assert(b.s[2] == 900);
};
@test fn slicefield_viaptr_2lvl() void = {
let a: [3]int = [700: int, 800: int, 900: int];
let b: sfv_box;
let p = &b;
p.s = a[0:3];
assert(p.s.len == 3);
assert(p.s[2] == 900);
};
@test fn slicefield_chainstore_2lvl() void = {
let a: [3]int = [700: int, 800: int, 900: int];
let v: sfc_outer;
v.i.s = a[0:3];
assert(v.i.s.len == 3);
assert(v.i.s[2] == 900);
};
@test fn slicefield_ptrchain_2lvl() void = {
let a: [3]int = [700: int, 800: int, 900: int];
let i: sfp_inner;
i.n = 1;
let v: sfp_outer;
v.pi = &i;
v.pi.s = a[0:3];
assert(i.s.len == 3);
assert(i.s[2] == 900);
};
@test fn slicefield_chainread_2lvl() void = {
let a: [3]int = [700: int, 800: int, 900: int];
let v: sfcr_outer;
v.i.s = a[0:3];
let k = sfcr_noise(9);
assert(k == 66);
let w = v.i.s;
assert(w.len == 3);
};
@test fn slicefield_ptrread_2lvl() void = {
let a: [3]int = [700: int, 800: int, 900: int];
let b: sfpr_box;
b.s = a[0:3];
let p = &b;
let k = sfpr_noise(9);
assert(k == 66);
let w = p.s;
assert(w.len == 3);
};
@test fn slicefield_wholeread_2lvl() void = {
let a: [3]int = [700: int, 800: int, 900: int];
let b: sfw_box;
b.s = a[0:3];
let k = sfw_noise(9);
assert(k == 66);
let w = b.s;
assert(w.len == 3);
assert(w[2] == 900);
};
@test fn slicefield_idx_tripwire_73() void = {
let a: [3]int = [700: int, 800: int, 900: int];
let xs: [2]sfi_box;
xs[0].s = a[0:3];
assert(xs[0].s.len == 3);
};
@test fn idx_2level() void = {
let a: idx_arr2 = [1000: int, 2000: int, 3000: int, 4000: int];
assert(a[2] == 3000);
a[1] = 9999;
assert(a[1] == 9999);
};
@test fn slice_2level() void = {
let a: [4]int = [1000: int, 2000: int, 3000: int, 4000: int];
let s: sl2_sl2 = a[1:3];
assert(s.len == 2);
assert(s[0] == 2000);
s[1] = 7777;
assert(a[2] == 7777);
};
@test fn range_2level() void = {
let a: rng_arr2 = [1: int, 2: int, 3: int, 4: int];
let sum: int = 0;
for (let x .. a) {
sum = sum + x;
};
assert(sum == 10);
};
@test fn slice_of_alias_arg() void = {
let a: soa_arr2 = [1000: int, 2000: int, 3000: int, 4000: int];
let s = a[1:3];
assert(s.len == 2);
assert(s[1] == 3000);
assert(soa_sum(a[0:4]) == 10000);
};
@test fn float_alias_param_kenv3() void = {
assert(fak_take(1.5) == 3.0);
};
@test fn float_alias_param() void = {
let v: fap_f2t = 5.0;
assert(fap_half(v) == 2.5);
};
@test fn str_alias_2level() void = {
let v: sa2_s2t = "hello";
assert(v.len == 5);
assert(sa2_taillen(v) == 5);
let w: sa2_s2t = v;
assert(w.len == 5);
};
@test fn slice_alias_param() void = {
let a: [3]int = [1000: int, 2000: int, 3000: int];
let s: slp_b2 = a[0:3];
assert(slp_first(s) == 1000);
};
@test fn arg_2level_fwdref() void = {
let x: afr_ali;
x.a = 4; x.b = 9; x.c = 13;
assert(afr_take(x) == 26);
};
@test fn arg_2level_litinit() void = {
let x: ali_st = ali_st { a = 4: size, b = 9: size, c = 13: size };
assert(ali_take(x) == 26);
};
@test fn arg_2level_5word() void = {
let v: a5_big2;
v.a = 1000; v.b = 2; v.c = 3; v.d = 4; v.e = 5000;
assert(a5_take(v) == 6000);
};
@test fn arg_2level_floatclass() void = {
let v: afc_fs2;
v.x = 2.5; v.n = 7;
assert(afc_take(v) == 7);
};
@test fn arg_base_control() void = {
let x: abc_base;
x.a = 4; x.b = 9; x.c = 13;
assert(abc_take(x) == 26);
};
@test fn union_store_norm() void = {
let x: usn_ali;
x.a = 4; x.b = 9;
let v: (void | usn_ali) = x;
match (v) {
case let s: usn_ali => {
assert(s.a == 4);
assert(s.b == 9);
};
case void => { assert(false); };
};
};
@test fn union_store_fwd() void = {
let x: usf_ali;
x.a = 4; x.b = 9;
let v: (void | usf_ali) = x;
match (v) {
case let s: usf_ali => {
assert(s.a == 4);
assert(s.b == 9);
};
case void => { assert(false); };
};
};
@test fn union_store_3word() void = {
let x: us3_ali;
x.a = 4; x.b = 9; x.c = 3;
let v: (void | us3_ali) = x;
match (v) {
case let s: us3_ali => {
assert(s.a == 4);
assert(s.c == 3);
};
case void => { assert(false); };
};
};
@test fn union_push_arg() void = {
let x: upa_ali;
x.a = 4; x.b = 9;
assert(upa_peek(x) == 9);
};
@test fn union_store_base_ctl() void = {
let x: usbc_base;
x.a = 4; x.b = 9; x.c = 3;
let v: (void | usbc_base) = x;
match (v) {
case let s: usbc_base => {
assert(s.a == 4);
assert(s.c == 3);
};
case void => { assert(false); };
};
};
@test fn union_slit_base_ctl() void = {
let v: (void | uslbc_base) = uslbc_base{a=4000, b=9000};
match (v) {
case let s: uslbc_base => {
assert(s.a == 4000);
assert(s.b == 9000);
};
case void => { assert(false); };
};
};
@test fn union_slit_alias() void = {
let v: (void | usla_ali) = usla_ali{a=4000, b=9000};
match (v) {
case let s: usla_ali => {
assert(s.a == 4000);
assert(s.b == 9000);
};
case void => { assert(false); };
};
};
@test fn union_slit_alias2() void = {
let v: (void | usl2_ali2) = usl2_ali2{a=4000, b=9000};
match (v) {
case let s: usl2_ali2 => {
assert(s.a == 4000);
assert(s.b == 9000);
};
case void => { assert(false); };
};
};
@test fn union_slit_order() void = {
let v: (void | uslo_ali) = uslo_ali{a=4000, b=9000};
match (v) {
case let s: uslo_ali => {
assert(s.a == 4000);
assert(s.b == 9000);
};
case void => { assert(false); };
};
};
@test fn castprim_3lvl_base() void = {
let x: cp3_s3;
x.f = 70000;
let y: u64 = (x.f: u32): u64;
assert(y == 70000);
};
@test fn castprim_ptr2lvl_base() void = {
let x: cpp_s2;
x.f = 70000;
let p: *cpp_s2 = &x;
let y: u64 = (p.f: u32): u64;
assert(y == 70000);
};
@test fn castprim_2lvl_base_ctl() void = {
let x: cp2_s2;
x.f = 70000;
let y: u64 = (x.f: u32): u64;
assert(y == 70000);
};
@test fn untyped_hold33_pin() void = {
let mn: (void | size) = 5;
assert(mn is size);
};
@test fn untyped_tagdst_2lvl_hold() void = {
let v: utd_r2 = 5;
assert(v is size);
};
@test fn untyped_str2lvl_ctl() void = {
let v: (void | usc_sa2) = "hi";
assert(v is usc_sa2);
};
@test fn untyped_int2lvl_ctl() void = {
let v: (void | uic_ia2) = 7;
assert(v is uic_ia2);
};
@test fn untyped_bool1lvl_ctl() void = {
let v: (void | ub1_ba1) = true;
assert(v is ub1_ba1);
};
@test fn untyped_bool2lvl_bound90() void = {
let v: (void | ub2_bb2) = true;
assert(v is ub2_bb2);
};
@test fn v2_ctrl() void = {
let x: i64 = 7;
let v: (void | v2c_pc) = &x;
assert(v is v2c_pc);
};
@test fn v2_alias2() void = {
let x: i64 = 7;
let v: (void | v2a_pb) = &x;
assert(v is v2a_pb);
};
@test fn sp_alias1() void = {
let v: sp1_outer = 5: i64;
assert(v is i64);
};
@test fn sp_alias2() void = {
let v: sp2_outer = 5: i64;
assert(v is i64);
};
@test fn amplen_plain() void = {
let s: []i64 = [1, 2, 3];
let p: *i64 = &s.len;
assert(*p == 3);
};
@test fn rangevar_alias2() void = {
let a: [4]int = [10: int, 20: int, 30: int, 40: int];
let t: rva_slk = a[2:];
assert(t.len == 2);
assert(t.cap == 2);
let sum: int = 0;
for (let x .. t) { sum = sum + 0 * x + 1; };
assert(sum == 2);
};
@test fn rangevar_plain_ctl() void = {
let a: [4]int = [10: int, 20: int, 30: int, 40: int];
let t: []int = a[2:];
let sum: int = 0;
for (let x .. t) { sum = sum + 0 * x + 1; };
assert(sum == 2);
};
@test fn nested_alias_field_norm() void = {
let v: nfn_outer;
v.x.a = 4; v.x.b = 9;
v.y.a = 7; v.y.b = 3;
assert(v.x.b == 9);
assert(v.y.b == 3);
};
@test fn nested_alias_field_fwd() void = {
let v: nff_outer;
v.x.a = 4; v.x.b = 9;
v.y.a = 7; v.y.b = 3;
assert(v.x.b == 9);
assert(v.y.b == 3);
let pa = &v.y.b;
*pa = 11;
assert(v.y.b == 11);
};

View File

@@ -0,0 +1,378 @@
// alias_cgen_b5_test — #5 alias arc F2b (B5 train): the cstage cgen helper +
// funnel internalization through type_chase_named (c1), the #73 tripwire
// graduation (c2), the #89 cgreturn return-position widen (c3) and the #93
// deref-index pointee chase (c4). Each was a 2-level (alias-over-alias) or
// 1-level-over-named type whose cgen site single-peeled the TY_NAMED layer:
// tagged_arg_size sized a union param to 0, the #73 tripwire fataled at indexed
// struct-field store/read, cgreturn dropped the un-widened payload (silent exit
// 1), and the N_UN(STAR) pointee classify missed the array skip on a 2-level
// alias array (one spurious MOVQ (AX),AX → SEGV). All graduated to 0/0 byte-id
// by chasing the alias at the cgen site; ww was the runtime-correct reference
// for the #263-polarity rows. Migrated from test/wcc/944_alias_cgen_b5_run.c
// (#5-C3); the C driver ran each row both stages + asserted cs==ww exit, here
// the cstage run is test-lang (T1) and byte-id is test-lang-byteid (T2). The
// fill0/fill2 loud-pair, g73_static_str (#129 loud) and g73_heapfill
// (compile-only) rows live elsewhere (separate kinds).
package alias_cgen_b5_test;
// --- c1: signed_ctl
type signed_s0 = i8;
type signed_s1 = signed_s0;
type signed_st = struct { f: signed_s1, g: signed_s1 };
// --- c1: targ_2lvl / wpush_2lvl share the (void|i64) 2-lvl alias + matcher.
type targ_u0 = (void | i64);
type targ_u = targ_u0;
fn targ_h(v: targ_u) i32 = {
match (v) {
case let n: i64 => { if (n != 42) { return 1; }; return 0; };
case void => { return 2; };
};
};
// --- c1: tmem_2lvl (>48B MEMORY-class twin)
type tmem_big = struct { a: i64, b: i64, c: i64, d: i64, e: i64, f: i64, g: i64 };
type tmem_m0 = (void | tmem_big);
type tmem_m = tmem_m0;
fn tmem_h(v: tmem_m) i32 = {
match (v) {
case let s: tmem_big => { if (s.g != 77) { return 1; }; return 0; };
case void => { return 2; };
};
};
// --- c1: wstore_2lvl
type wstore_u0 = (void | i64);
type wstore_u = wstore_u0;
// --- c1: wstore_1lvl
type wstore1_u = (void | i64);
// --- c1: wstore_a_2lvl
type wstorea_u0 = (void | i64);
type wstorea_u = wstorea_u0;
// --- c1: succ_2lvl (`?`-success remap over 2-lvl alias result)
type succ_e0 = !i64;
type succ_r0 = (i64 | succ_e0);
type succ_r = succ_r0;
fn succ_w(bad: bool) succ_r = {
if (bad) { return 7: succ_e0; };
return 42;
};
fn succ_outer() succ_r = {
let v = succ_w(false)?;
return v + 1;
};
// --- c1: null_2lvl
type null_np0 = (*i64 | void);
type null_np = null_np0;
// --- c1: f32p_2lvl
type f32p_in0 = struct { a: f64 };
type f32p_in1 = f32p_in0;
type f32p_pt = struct { x: f32p_in1, y: f64 };
fn f32p_g(p: f32p_pt) f64 = { return p.x.a + p.y; };
// --- c1: tuparg_bound99 / tuparg_cast_bound99 (2-lvl alias tuple param)
type tparg_tp0 = (i64, i64);
type tparg_tp = tparg_tp0;
fn tparg_f(t: tparg_tp) i64 = { return t.0 + t.1; };
// --- c1: tuparg1_bound99 (1-level identical, not alias-depth)
type tparg1_tp = (i64, i64);
fn tparg1_f(t: tparg1_tp) i64 = { return t.0 + t.1; };
// --- c1: tupglobal_bound99 (alias-tuple module-global)
type tpglob_tp0 = (i64, i64);
type tpglob_tp = tpglob_tp0;
let tpglob_G: tpglob_tp = (4, 9);
// --- c2: g73_idxstore
type g73is_sl = []int;
type g73is_sl2 = g73is_sl;
type g73is_box = struct { s: g73is_sl2, n: int };
// --- c2: g73_strfield
type g73sf_s1t = str;
type g73sf_s2t = g73sf_s1t;
type g73sf_box = struct { s: g73sf_s2t, n: int };
fn g73sf_noise(x: int) int = { return x * 7 + 3; };
// --- c2: g73_tagfield
type g73tf_tu0 = (void | i64);
type g73tf_tu = g73tf_tu0;
type g73tf_box = struct { u: g73tf_tu, n: int };
// --- c2: g73_idxread
type g73ir_sl = []int;
type g73ir_sl2 = g73ir_sl;
type g73ir_box = struct { s: g73ir_sl2, n: int };
fn g73ir_noise(x: int) int = { return x * 7 + 3; };
// --- c2: g73_ptrread
type g73pr_sl = []int;
type g73pr_sl2 = g73pr_sl;
type g73pr_inner = struct { s: g73pr_sl2, n: int };
type g73pr_outer = struct { pi: *g73pr_inner };
fn g73pr_noise(x: int) int = { return x * 7 + 3; };
// --- c2: g73_tupread
type g73tr_sl = []int;
type g73tr_sl2 = g73tr_sl;
// --- c2: g73_static_struct (alias-tuple/struct module-global)
type g73ss_in0 = struct { a: i64, b: i64 };
type g73ss_in1 = g73ss_in0;
type g73ss_box = struct { i: g73ss_in1, n: i64 };
let g73ss_g: g73ss_box = g73ss_box { i = g73ss_in0 { a = 4, b = 9 }, n = 5 };
// --- c3: g89_ret_widen
type g89w_base = struct { a: size, b: size };
type g89w_ali = g89w_base;
fn g89w_mk() (void | g89w_ali) = {
let x: g89w_ali;
x.a = 4; x.b = 9;
return x;
};
// --- c3: g89_ret_errunion
type g89e_failure = struct { code: i32, aux: size };
type g89e_myerr = g89e_failure;
fn g89e_work(bad: bool) (i32 | g89e_myerr) = {
if (bad) {
let e: g89e_myerr;
e.code = 7; e.aux = 99;
return e;
};
return 42;
};
// --- c3: g89_ret_named_ctl (bare NAMED struct return control)
type g89c_base = struct { a: size, b: size };
fn g89c_make() (void | g89c_base) = {
let x: g89c_base;
x.a = 4; x.b = 9;
return x;
};
// --- c4: g93_l2_local
type g93l_arr = [3]int;
type g93l_arr2 = g93l_arr;
// --- c4: g93_def (def twin over a 2-lvl alias def array)
type g93d_arr0 = [3]i64;
type g93d_arr = g93d_arr0;
def g93d_D: g93d_arr = [18i64, 29i64, 40i64];
// --- c4: g93_1lvl_ctl (1-level pointee control)
type g93c_arr = [3]int;
// ===== c1: helper + funnel internalization =====
@test fn signed_ctl() void = {
let x: signed_st;
x.f = -5;
x.g = 3;
assert(x.f < 0);
let w: i64 = x.f: i64;
assert(w == -5);
};
@test fn targ_2lvl() void = {
let x: targ_u = 42i64;
assert(targ_h(x) == 0);
};
@test fn tmem_2lvl() void = {
let s: tmem_big;
s.a = 11; s.b = 22; s.c = 33; s.d = 44; s.e = 55; s.f = 66; s.g = 77;
let x: tmem_m = s;
assert(tmem_h(x) == 0);
};
@test fn wpush_2lvl() void = {
assert(targ_h(42i64) == 0);
};
@test fn wstore_2lvl() void = {
let v: wstore_u = 42i64;
match (v) {
case let n: i64 => { assert(n == 42); };
case void => { assert(false); };
};
};
@test fn wstore_1lvl() void = {
let v: wstore1_u = 42i64;
match (v) {
case let n: i64 => { assert(n == 42); };
case void => { assert(false); };
};
};
@test fn wstore_a_2lvl() void = {
let v: wstorea_u = void;
v = 42i64;
match (v) {
case let n: i64 => { assert(n == 42); };
case void => { assert(false); };
};
};
@test fn succ_2lvl() void = {
match (succ_outer()) {
case let n: i64 => { assert(n == 43); };
case succ_e0 => { assert(false); };
};
};
@test fn null_2lvl() void = {
let n: i64 = 31;
let p: null_np = &n;
match (p) {
case let q: *i64 => { assert(*q == 31); };
case void => { assert(false); };
};
};
@test fn f32p_2lvl() void = {
let p: f32p_pt;
p.x.a = 2.5;
p.y = 1.5;
assert(f32p_g(p) == 4.0);
};
@test fn tuparg_bound99() void = {
let t: tparg_tp = (4, 9);
assert(tparg_f(t) == 13);
};
@test fn tuparg1_bound99() void = {
let t: tparg1_tp = (4, 9);
assert(tparg1_f(t) == 13);
};
@test fn tuparg_cast_bound99() void = {
let t: tparg_tp = (4, 9): tparg_tp;
assert(tparg_f(t) == 13);
};
@test fn tupglobal_bound99() void = {
assert(tpglob_G.0 + tpglob_G.1 == 13);
};
// ===== c2: #73 graduation =====
@test fn g73_idxstore() void = {
let a: [3]int = [700: int, 800: int, 900: int];
let xs: [2]g73is_box;
xs[0].s = a[0:3];
assert(xs[0].s.len == 3);
};
@test fn g73_strfield() void = {
let xs: [2]g73sf_box;
xs[1].s = "hello";
xs[1].n = 4;
let k = g73sf_noise(9);
assert(k == 66);
let w = xs[1].s;
assert(w.len == 5);
};
@test fn g73_tagfield() void = {
let xs: [2]g73tf_box;
xs[0].n = 5;
xs[0].u = 42i64;
assert(xs[0].n == 5);
match (xs[0].u) {
case let v: i64 => { assert(v == 42); };
case void => { assert(false); };
};
};
@test fn g73_idxread() void = {
let a: [3]int = [700: int, 800: int, 900: int];
let xs: [2]g73ir_box;
let p = &xs[1];
p.s = a[0:3];
p.n = 4;
let k = g73ir_noise(9);
assert(k == 66);
let w = xs[1].s;
assert(w.len == 3);
assert(w[2] == 900);
};
@test fn g73_ptrread() void = {
let a: [3]int = [700: int, 800: int, 900: int];
let i: g73pr_inner;
i.s = a[0:3];
i.n = 1;
let v: g73pr_outer;
v.pi = &i;
let k = g73pr_noise(9);
assert(k == 66);
let w = v.pi.s;
assert(w.len == 3);
assert(w[2] == 900);
};
@test fn g73_tupread() void = {
let a: [3]int = [700: int, 800: int, 900: int];
let t: (g73tr_sl2, int) = (a[0:3], 5);
let s = t.0;
assert(s.len == 3);
assert(t.1 == 5);
};
@test fn g73_static_struct() void = {
assert(g73ss_g.n == 5);
assert(g73ss_g.i.b == 9);
};
// ===== c3: #89 cgreturn return-position widen =====
@test fn g89_ret_widen() void = {
match (g89w_mk()) {
case let s: g89w_ali => { assert(s.b == 9); };
case void => { assert(false); };
};
};
@test fn g89_ret_errunion() void = {
match (g89e_work(true)) {
case let e: g89e_myerr => { assert(e.aux == 99); };
case i32 => { assert(false); };
};
};
@test fn g89_ret_named_ctl() void = {
let v = g89c_make();
match (v) {
case let s: g89c_base => { assert(s.b == 9); };
case void => { assert(false); };
};
};
// ===== c4: #93 deref-index pointee chase =====
@test fn g93_l2_local() void = {
let a: g93l_arr2 = [1000: int, 2000: int, 3000: int];
let p: *g93l_arr2 = &a;
assert((*p)[2] == 3000);
};
@test fn g93_def() void = {
let p: *g93d_arr = &g93d_D;
assert((*p)[2] == 40i64);
};
@test fn g93_1lvl_ctl() void = {
let a: g93c_arr = [1000: int, 2000: int, 3000: int];
let p: *g93c_arr = &a;
assert((*p)[2] == 3000);
};

View File

@@ -0,0 +1,271 @@
// alias_cgen_b6_test — #5 alias arc F2b (B6 train): the cgen.c cgexpr/cgstmt
// INLINE single-peel sweep through type_chase_named, by consumer family —
// c1 assign/reassign, c2 call-arg, c3 addr-of/field-walk/index spine,
// c4 cast/is/try, c5 reads/len/globals. Every K_RUN row was a cs-side
// single-peel that left a 2-level alias TY_NAMED (or ww the alias-blind side
// at the c3 index/field gates, graduated by W2 #102): silent-wrong store
// width, wrong stride, alias-blind field offset. Migrated from
// test/wcc/944_alias_cgen_b6_run.c (#5-C3).
//
// The 3 K_BUILDERR/loud rows (fsarg0_loud_ctl, fsarg2_bound, try_loud_38b)
// live elsewhere — value rows only here. Per-row type/global/fn families are
// prefixed to dedup the source's reused {ms,st,fs,u,big,S,my32,...} spellings
// at module scope (ww forbids local `type`); forward-ref decl order is
// irrelevant to value semantics here so families are declared base-first.
package alias_cgen_b6_test;
// ---- c1: assign/reassign family
type c1sr_ms0 = str;
type c1sr_ms = c1sr_ms0;
@test fn streassign_2lvl() void = {
let a: c1sr_ms = "hello";
let b: c1sr_ms = "x";
b = a;
assert(len(b) == 5);
};
type c1ra_st0 = struct { a: i64, b: i64, c: i64 };
type c1ra_st = c1ra_st0;
@test fn sreassign_2lvl() void = {
let x: c1ra_st; x.a = 1; x.b = 2; x.c = 3;
let y: c1ra_st; y.a = 0; y.b = 0; y.c = 0;
y = x;
assert(y.c == 3 && y.b == 2);
};
type c1da_st0 = struct { a: i64, b: i64 };
type c1da_st = c1da_st0;
@test fn dassign_2lvl() void = {
let x: c1da_st; x.a = 1; x.b = 2;
let p: *c1da_st = &x;
(*p).b = 9;
assert(x.b == 9);
};
// ---- c2: call-arg family
type c2fi_fs0 = struct { x: f64 };
type c2fi_fs = c2fi_fs0;
fn c2fi_mk() c2fi_fs0 = {
let s: c2fi_fs0; s.x = 2.5;
return s;
};
fn c2fi_g(p: c2fi_fs) f64 = { return p.x; };
@test fn fsarg_ident_ctl() void = {
let v: c2fi_fs = c2fi_mk();
assert(c2fi_g(v) == 2.5);
};
type c2sa_big0 = struct { a: i64, b: i64, c: i64 };
type c2sa_big = c2sa_big0;
fn c2sa_g(p: c2sa_big) i64 = { return p.a + p.c; };
@test fn sarg_2lvl() void = {
let s: c2sa_big; s.a = 4; s.b = 5; s.c = 9;
assert(c2sa_g(s) == 13);
};
type c2st_ms0 = str;
type c2st_ms = c2st_ms0;
fn c2st_g(s: c2st_ms) i64 = { return len(s): i64; };
@test fn strarg_2lvl() void = {
let a: c2st_ms = "hello";
assert(c2st_g(a) == 5);
};
// ---- c3: addr-of/field-walk/index spine
type c3if_el0 = struct { a: i64, b: i64 };
type c3if_el = c3if_el0;
// graduated: #102 (W2)
@test fn idxf_2lvl() void = {
let xs: [2]c3if_el;
xs[0].a = 1; xs[0].b = 2;
xs[1].a = 3; xs[1].b = 4;
assert(xs[1].b == 4 && xs[0].b == 2);
};
type c3ifp_el0 = struct { a: i64, b: i64 };
@test fn idxf_plain_ctl() void = {
let xs: [2]c3ifp_el0;
xs[0].a = 1; xs[0].b = 2;
xs[1].a = 3; xs[1].b = 4;
assert(xs[1].b == 4 && xs[0].b == 2);
};
type c3af_st0 = struct { a: i64, b: i64 };
type c3af_st = c3af_st0;
// graduated: #102 (W2)
@test fn ampf_2lvl() void = {
let x: c3af_st; x.a = 1; x.b = 2;
let p: *c3af_st = &x;
let q: *i64 = &p.b;
*q = 9;
assert(x.b == 9);
};
type c3afp_st0 = struct { a: i64, b: i64 };
@test fn ampf_plain_ctl() void = {
let x: c3afp_st0; x.a = 1; x.b = 2;
let p: *c3afp_st0 = &x;
let q: *i64 = &p.b;
*q = 9;
assert(x.b == 9);
};
type c3av_st0 = struct { a: i64, b: i64 };
type c3av_st = c3av_st0;
// amendment: #102 (W2)
@test fn ampv_2lvl() void = {
let x: c3av_st; x.a = 1; x.b = 2;
let q: *i64 = &x.b;
*q = 9;
assert(x.b == 9);
};
type c3avp_st0 = struct { a: i64, b: i64 };
@test fn ampv_plain_ctl() void = {
let x: c3avp_st0; x.a = 1; x.b = 2;
let q: *i64 = &x.b;
*q = 9;
assert(x.b == 9);
};
type c3cd_in0 = struct { v: i64 };
type c3cd_in1 = c3cd_in0;
type c3cd_out0 = struct { inner: c3cd_in1, n: i64 };
type c3cd_out1 = c3cd_out0;
@test fn chdot_2lvl() void = {
let s: c3cd_out1; s.inner.v = 7; s.n = 3;
let p: *c3cd_out1 = &s;
assert(p.inner.v == 7);
};
type c3es_my32 = u32;
type c3es_my32b = c3es_my32;
@test fn esub_2lvl() void = {
let xs: [3]c3es_my32b;
xs[0] = 5; xs[1] = 6; xs[2] = 7;
assert(xs[0]: i64 + xs[1]: i64 + xs[2]: i64 == 18);
};
type c3kw_my32 = u32;
type c3kw_S = struct { arr: [3]c3kw_my32, n: int };
@test fn kw1_101() void = {
let s = c3kw_S { arr = [10u32, 20u32, 30u32], n = 4 };
assert(s.arr[0] + s.arr[1] + s.arr[2] == 60u32);
assert(s.n == 4);
};
type c3kc_my16 = u16;
type c3kc_S2 = struct { arr: [4]c3kc_my16, n: int };
@test fn kw1_ctl16() void = {
let s = c3kc_S2 { arr = [1u16, 2u16, 3u16, 4u16], n = 9 };
assert(s.arr[0] + s.arr[1] + s.arr[2] + s.arr[3] == 10u16);
assert(s.n == 9);
};
// ---- c4: cast/is/try family
type c4sc_ms0 = str;
type c4sc_ms = c4sc_ms0;
@test fn strcast_2lvl() void = {
let a: c4sc_ms = "hey";
let b: []u8 = a: []u8;
assert(len(b) == 3);
assert(b[0] == 'h');
};
type c4ic_u0 = (void | i64);
type c4ic_u = c4ic_u0;
@test fn idcast_2lvl() void = {
let v: c4ic_u = 42i64;
let w: c4ic_u = (v: c4ic_u);
match (w) {
case let n: i64 => { assert(n == 42); };
case void => { assert(false); };
};
};
type c4is_u0 = (void | i64);
type c4is_u = c4is_u0;
@test fn is_2lvl() void = {
let v: c4is_u = 42i64;
assert(v is i64);
assert(!(v is void));
};
// ---- c5: reads/len/globals family
type c5tf_u0 = (void | i64);
type c5tf_u = c5tf_u0;
type c5tf_st0 = struct { f: c5tf_u, n: i64 };
type c5tf_st = c5tf_st0;
@test fn tfread_2lvl() void = {
let s: c5tf_st;
s.f = 42i64;
s.n = 3;
assert(s.f is i64);
let p: *c5tf_st = &s;
assert(p.f is i64);
};
type c5ln_ms0 = str;
type c5ln_ms = c5ln_ms0;
type c5ln_ar0 = [4]i64;
type c5ln_ar = c5ln_ar0;
@test fn len_2lvl() void = {
let a: c5ln_ms = "hello";
assert(len(a) == 5);
let xs: c5ln_ar = [1, 2, 3, 4];
assert(len(xs) == 4);
};
type c5gr_my64 = i64;
type c5gr_my64b = c5gr_my64;
let c5gr_G: c5gr_my64b = 7;
@test fn gref_2lvl() void = {
assert(c5gr_G == 7);
};
type c5mr_big = struct { a: i64, b: i64, c: i64, d: i64, e: i64 };
type c5mr_m0 = (void | c5mr_big);
type c5mr_m = c5mr_m0;
@test fn memread_40b() void = {
let s: c5mr_big;
s.a = 1; s.b = 2; s.c = 3; s.d = 4; s.e = 55;
let v: c5mr_m = s;
assert(v is c5mr_big);
match (v) {
case let w: c5mr_big => { assert(w.e == 55); };
case void => { assert(false); };
};
};

View File

@@ -0,0 +1,37 @@
// alias_decl_order_size_runonly_test — the cs≠ww .s carve-out split from
// alias_decl_order_size_test (#5-C3, #7f/#254 value-only runonly home).
// Indexing an alias-NAMED array LOCAL is the task-#60 family: wwstage emits a
// ptr-load/ADDQ spine vs cstage's direct 8(BX) — PRE-EXISTING on master,
// order-INDEPENDENT, runtime-correct both stages (probe-verified cs≠ww .s at
// HEAD). The decl-order-independence + size assert + last-element readback
// stay pinned on the cstage run (T1); the file is *_runonly so the
// test-lang-byteid (T2) corpus excludes it. Flip back into the byte-id file
// when #60 lands. Migrated from test/wcc/944_alias_decl_order_size_run.c.
package alias_decl_order_size_runonly_test;
// arrelem_fwd: arr=[2]base declared BEFORE base (forward ref).
type aef_arr = [2]aef_base;
type aef_base = struct { a: size, b: size };
// arrelem_norm: base before arr.
type aen_base = struct { a: size, b: size };
type aen_arr = [2]aen_base;
@test fn arrelem_fwd() void = {
assert(size(aef_arr) == 32);
let a: aef_arr;
a[0].a = 4; a[0].b = 9; a[1].a = 7; a[1].b = 3;
assert(a[0].b == 9);
assert(a[1].a == 7);
assert(a[1].b == 3);
};
@test fn arrelem_norm() void = {
assert(size(aen_arr) == 32);
let a: aen_arr;
a[0].a = 4; a[0].b = 9; a[1].a = 7; a[1].b = 3;
assert(a[0].b == 9);
assert(a[1].a == 7);
assert(a[1].b == 3);
};

View File

@@ -0,0 +1,139 @@
// alias_decl_order_size_test — #62 rider (alias arc pre-F1): type-table layout
// must be DECL-ORDER-INDEPENDENT, migrated from
// test/wcc/944_alias_decl_order_size_run.c (#5-C3). cstage check_file resolved
// typedecl bodies in file order with an eager under->size copy, so a body
// referencing a LATER typedecl read its size-0 placeholder and baked it in
// (alias size 0, union maxsz 0, struct offsets collapsed, array stride 0).
// wwstage (demand-driven tinfofornode) was order-independent; cstage now
// mirrors via resolve-on-first-reference. Oracle: size((void|ali)) = 8B tag +
// roundup8(chased member size).
//
// FORWARD-REF FIDELITY: each row's decl-order is preserved at module scope by
// giving it its OWN type family — the *_f families declare an alias (or struct
// containing a field) BEFORE the type it references, which is exactly the
// forward reference the fix made sound. The C driver ran each row both stages
// + asserted cs==ww exit; here the cstage run is test-lang (T1) and byte-id is
// test-lang-byteid (T2). The arrelem index-over-alias rows (cs≠ww .s, #60) and
// the cycle BUILDERR rows live elsewhere (runonly_test + runww carriers).
package alias_decl_order_size_test;
// sizes_norm: base before alias.
type sn_base = struct { a: size, b: size };
type sn_ali = sn_base;
// sizes_fwd: alias BEFORE base (forward ref).
type sf_ali = sf_base;
type sf_base = struct { a: size, b: size };
// union_decl_norm: named u=(void|ali) declared LAST.
type udn_base = struct { a: size, b: size };
type udn_ali = udn_base;
type udn_u = (void | udn_ali);
// union_decl_fwd: named u declared FIRST, then ali, then base.
type udf_u = (void | udf_ali);
type udf_ali = udf_base;
type udf_base = struct { a: size, b: size };
// field_fwd: outer{i,j: inner} declared BEFORE inner.
type ff_outer = struct { i: ff_inner, j: ff_inner };
type ff_inner = struct { a: size, b: size };
// field_norm: inner before outer.
type fn_inner = struct { a: size, b: size };
type fn_outer = struct { i: fn_inner, j: fn_inner };
// chain2_fwd: a2=a1=base full forward chain.
type cf_a2 = cf_a1;
type cf_a1 = cf_base;
type cf_base = struct { a: size, b: size };
// chain2_norm: base, a1, a2 in order.
type cn_base = struct { a: size, b: size };
type cn_a1 = cn_base;
type cn_a2 = cn_a1;
// union_base_ctl: direct base member (m5b_match0 no-regress control).
type ubc_base = struct { a: size, b: size };
// ptr_selfref_ok: legal self-reference (pointer field never reads the
// target's size) must stay accepted — the io.stream / list-node shape.
type node = struct { v: size, next: *node };
@test fn sizes_norm() void = {
assert(size(sn_base) == 16);
assert(size(sn_ali) == 16);
assert(size((void | sn_ali)) == 24);
};
@test fn sizes_fwd() void = {
assert(size(sf_base) == 16);
assert(size(sf_ali) == 16);
assert(size((void | sf_ali)) == 24);
};
@test fn union_decl_norm() void = {
assert(size(udn_u) == 24);
};
@test fn union_decl_fwd() void = {
assert(size(udf_u) == 24);
};
// fwd field: a size-0 inner collapsed outer's offsets too — pin the LAST word
// of the SECOND field, values all distinct.
@test fn field_fwd() void = {
assert(size(ff_inner) == 16);
assert(size(ff_outer) == 32);
let o: ff_outer;
o.i.a = 4; o.i.b = 9; o.j.a = 7; o.j.b = 3;
assert(o.i.a == 4);
assert(o.i.b == 9);
assert(o.j.a == 7);
assert(o.j.b == 3);
};
@test fn field_norm() void = {
assert(size(fn_inner) == 16);
assert(size(fn_outer) == 32);
let o: fn_outer;
o.i.a = 4; o.i.b = 9; o.j.a = 7; o.j.b = 3;
assert(o.i.a == 4);
assert(o.i.b == 9);
assert(o.j.a == 7);
assert(o.j.b == 3);
};
@test fn chain2_fwd() void = {
assert(size(cf_a1) == 16);
assert(size(cf_a2) == 16);
};
@test fn chain2_norm() void = {
assert(size(cn_a1) == 16);
assert(size(cn_a2) == 16);
};
// m5b_match0 no-regress control: direct base member, full payload readback
// through the box, last word checked.
@test fn union_base_ctl() void = {
let x: ubc_base;
x.a = 4; x.b = 9;
let v: (void | ubc_base) = x;
match (v) {
case let s: ubc_base => {
assert(s.a == 4);
assert(s.b == 9);
};
case void => { assert(false); };
};
};
@test fn ptr_selfref_ok() void = {
let n: node;
n.v = 7;
n.next = &n;
assert(size(node) == 16);
assert(n.v == 7);
};

View File

@@ -0,0 +1,95 @@
// alias_emit_b7_test — #5 alias arc B7 (finale): the cgen static-DATA emitter
// ELEM-type alias chases, migrated from test/wcc/944_alias_emit_b7_run.c
// (#5-C3). The residual single peel was on the ELEMENT type (u->sub), so a
// 2-level-elem-alias global missed the TY_STRUCT / TY_STR kind tests and fell
// off the foldable-literal path: cs emitted NO DATA (link-loud, or latent
// silence when unreferenced) while ww always emitted. The fix chases the elem
// type at each emitter site; cs aligns UP onto ww's already-correct emit and
// the rows graduate to byte-id. `type el = el0` over a named struct is ALREADY
// two NAMED layers, so the "_1lvl" spelling graduates with the 2-level rows;
// only a direct alias of a primitive is a true single layer. The C driver ran
// each row both stages + asserted cs==ww exit; here the cstage run is
// test-lang (T1) and byte-id is test-lang-byteid (T2). The slice-of-{str,
// slice,tagged} BUILDERR rows and ww-checker-reject slice cells live elsewhere.
package alias_emit_b7_test;
// sarr_2lvl: [2]el 2-lvl alias struct — elem alias missed TY_STRUCT.
type sarr2_el0 = struct { a: i64, b: i64 };
type sarr2_el1 = sarr2_el0;
type sarr2_el = sarr2_el1;
let g_sarr2: [2]sarr2_el = [sarr2_el0 { a = 1, b = 2 }, sarr2_el0 { a = 3, b = 4 }];
// sarr_1lvl: [2]el, el = el0 — two NAMED layers by construction.
type sarr1_el0 = struct { a: i64, b: i64 };
type sarr1_el = sarr1_el0;
let g_sarr1: [2]sarr1_el = [sarr1_el0 { a = 1, b = 2 }, sarr1_el0 { a = 3, b = 4 }];
// sarr_plain_ctl: [2]el0 control.
type sarrc_el0 = struct { a: i64, b: i64 };
let g_sarrc: [2]sarrc_el0 = [sarrc_el0 { a = 1, b = 2 }, sarrc_el0 { a = 3, b = 4 }];
// sarr_unref_2lvl: NEVER-REFERENCED 2-lvl-elem global — pre-B7 cs silently
// lacked DATA (no reference → no link error → latent silence). The byte-id vs
// ww (which always emitted) is the closure pin.
type sarru_el0 = struct { a: i64, b: i64 };
type sarru_el1 = sarru_el0;
type sarru_el = sarru_el1;
let g_sarru: [2]sarru_el = [sarru_el0 { a = 1, b = 2 }, sarru_el0 { a = 3, b = 4 }];
// strarr_2lvl: [2]ms 2-lvl alias str — eu != TY_STR → generic path can't fold
// strlits → link-loud. Also pins letpreintern's intern-order coupling.
type strarr2_ms0 = str;
type strarr2_ms = strarr2_ms0;
let g_strarr2: [2]strarr2_ms = ["aa", "bbb"];
// strarr_1lvl_ctl: type ms = str — TRUE 1-level; worked pre-B7, byte-neutral.
type strarr1_ms = str;
let g_strarr1: [2]strarr1_ms = ["aa", "bbb"];
// strarr_plain_ctl: [2]str control.
let g_strarrc: [2]str = ["aa", "bbb"];
// scalararr_2lvl: [3]my64b raw-bytes path — scalar fold never consulted eu,
// worked pre-B7, byte-neutral regression net.
type scalararr_my64 = i64;
type scalararr_my64b = scalararr_my64;
let g_scalararr: [3]scalararr_my64b = [5, 6, 7];
@test fn sarr_2lvl() void = {
assert(g_sarr2[0].a + g_sarr2[0].b + g_sarr2[1].a + g_sarr2[1].b == 10);
};
@test fn sarr_1lvl() void = {
assert(g_sarr1[0].a + g_sarr1[0].b + g_sarr1[1].a + g_sarr1[1].b == 10);
};
@test fn sarr_plain_ctl() void = {
assert(g_sarrc[0].a + g_sarrc[0].b + g_sarrc[1].a + g_sarrc[1].b == 10);
};
// zero-consumer latent-silence pin: the global is never read in the C source's
// main, so its DATA emit is asserted only by the byte-id (T2) gate; the T1 run
// merely exercises the def's presence.
@test fn sarr_unref_2lvl() void = {
assert(g_sarru[0].a + g_sarru[0].b + g_sarru[1].a + g_sarru[1].b == 10);
};
@test fn strarr_2lvl() void = {
assert(len(g_strarr2[0]) == 2);
assert(len(g_strarr2[1]) == 3);
};
@test fn strarr_1lvl_ctl() void = {
assert(len(g_strarr1[0]) == 2);
assert(len(g_strarr1[1]) == 3);
};
@test fn strarr_plain_ctl() void = {
assert(len(g_strarrc[0]) == 2);
assert(len(g_strarrc[1]) == 3);
};
@test fn scalararr_2lvl() void = {
assert(g_scalararr[0] + g_scalararr[1] + g_scalararr[2] == 18);
};

View File

@@ -0,0 +1,179 @@
// alias_global_decl_test — g-fold (#77 + #78 fused): alias-typed GLOBAL
// declarations, migrated from test/wcc/944_alias_global_decl_run.c (#5-C3).
// The decl/emit dispatch was alias-blind on both sides: cs (#78) single-peeled
// the let_* helper family so a 2-level alias chain (or one user alias over a
// named struct) left the type TY_NAMED, emitted no DATA, and read frame-local
// at offset 0 (saved-BP reads / SEGV); ww (#77) keyed emitletdataw's array gate
// on the UNCHASED N_TARRAY tnode so an alias-typed global ARRAY got `undefined
// reference to main.g`. Both fixed by ONE tichase at the dispatch entry.
//
// This table is the PERMANENT GUARD: the global decl path is lint-invisible
// (ww side is a no-peel consumer; cs helpers spell the one chased accessor).
// Values exceed 255 (no little-endian prefix-luck) and readbacks assert the
// LAST element. The C driver ran each row both stages + asserted cs==ww exit;
// here the cstage run is test-lang (T1) and byte-id is test-lang-byteid (T2).
// The *_ord rows' decl-after-let dimension is subsumed by module-level
// resolution (already order-independent), kept for row-count fidelity.
package alias_global_decl_test;
type t_arr = [4]int;
type t_arr2 = t_arr;
type t_au = [4]u32;
type t_myint = int;
type t_myint2 = t_myint;
type t_ms = str;
type t_ms2 = t_ms;
type t_mf = f64;
type t_mf2 = t_mf;
type t_mg = f32;
type t_mg2 = t_mg;
type t_pt = struct { x: int, y: int };
type t_pt1 = t_pt;
type t_pt2 = t_pt1;
type t_sl = []int;
type t_sl2 = t_sl;
type t_sa = [2]str;
type t_sa2 = t_sa;
type t_row = [3]int;
let g_ctl: [4]int = [1001: int, 1002: int, 1003: int, 1004: int];
let g_a1r: t_arr = [1001: int, 1002: int, 1003: int, 1004: int];
let g_a1w: t_arr = [1001: int, 1002: int, 1003: int, 1004: int];
let g_aord: t_arr = [1001: int, 1002: int, 1003: int, 1004: int];
let g_a2r: t_arr2 = [1001: int, 1002: int, 1003: int, 1004: int];
let g_a2o: t_arr2 = [1001: int, 1002: int, 1003: int, 1004: int];
let g_u32: t_au = [1001: u32, 1002: u32, 1003: u32, 1004: u32];
let g_sc2: t_myint2 = 4242;
let g_sc2o: t_myint2 = 4242;
let g_str2: t_ms2 = "hello";
let g_flt2: t_mf2 = 1.5;
let g_flt2f: t_mg2 = 1.5f32;
let g_st1: t_pt1;
let g_st2: t_pt2;
let g_stlit: t_pt1 = t_pt { x = 1001, y = 2002 };
let g_sl2: t_sl2 = [1001: int, 1002: int, 1003: int];
let g_sarr1: t_sa = ["hello", "worlds!"];
let g_sarr2: t_sa2 = ["hello", "worlds!"];
def G_a2: t_arr2 = [1001: int, 1002: int, 1003: int, 1004: int];
def G_st: t_pt1 = t_pt { x = 1001, y = 2002 };
def G_f2: t_mf2 = 1.5;
let g_hsl: t_sl = [1001: int, 1002: int, 1003: int];
let g_helem: [2]t_row = [[1010: int, 1020: int, 1030: int], [1040: int, 1050: int, 1060: int]];
@test fn ctl_plain() void = {
assert(g_ctl[3] == 1004);
g_ctl[3] = 9999;
assert(g_ctl[3] == 9999);
};
@test fn garr1_read() void = {
assert(g_a1r[0] == 1001);
assert(g_a1r[3] == 1004);
};
@test fn garr1_wr() void = {
g_a1w[3] = 8888;
assert(g_a1w[3] == 8888);
assert(g_a1w[2] == 1003);
};
@test fn garr_ord() void = {
assert(g_aord[3] == 1004);
};
// #78 headline: pre-fix cs emitted NO DATA and read the saved-BP word.
@test fn garr2_read() void = {
assert(g_a2r[0] == 1001);
assert(g_a2r[3] == 1004);
};
@test fn garr2_ordwr() void = {
assert(g_a2o[3] == 1004);
g_a2o[1] = 7777;
assert(g_a2o[1] == 7777);
};
@test fn garr_u32() void = {
assert(g_u32[3] == 1004);
g_u32[3] = 8888;
assert(g_u32[3] == 8888);
assert(g_u32[2] == 1003);
};
@test fn gsc2() void = {
assert(g_sc2 == 4242);
g_sc2 = 9999;
assert(g_sc2 == 9999);
};
@test fn gsc2_ord() void = {
assert(g_sc2o == 4242);
};
@test fn gstr2() void = {
assert(g_str2.len == 5);
};
@test fn gflt2() void = {
assert(g_flt2 == 1.5);
};
@test fn gflt2_f32() void = {
assert(g_flt2f == 1.5f32);
};
// one user alias level sufficed to SEGV cs pre-fix (the named struct already
// costs the single peel, so `pt1 = pt` is two TY_NAMED layers at the decl).
@test fn gst1() void = {
g_st1.y = 2002;
assert(g_st1.y == 2002);
};
@test fn gst2() void = {
g_st2.y = 2002;
assert(g_st2.y == 2002);
};
@test fn gstlit() void = {
assert(g_stlit.y == 2002);
};
@test fn gsl2() void = {
assert(g_sl2.len == 3);
assert(g_sl2[2] == 1003);
};
// [N]str rows also pin letpreintern's chased array-leg gate: a missed
// pre-intern desyncs _S_ label order vs cstage (byte-id catches it).
@test fn gstrarr1() void = {
assert(g_sarr1[1].len == 7);
};
@test fn gstrarr2() void = {
assert(g_sarr2[1].len == 7);
};
@test fn gdef_a2() void = {
assert(G_a2[3] == 1004);
};
@test fn gdef_st() void = {
assert(G_st.y == 2002);
};
@test fn gdef_f2() void = {
assert(G_f2 == 1.5);
};
// no-regression holds: alias global SLICE (green before the fold) and alias
// ELEMENT type (batch-1 win).
@test fn hold_slice1() void = {
assert(g_hsl.len == 3);
assert(g_hsl[2] == 1003);
};
@test fn hold_elem() void = {
assert(g_helem[0][0] == 1010);
assert(g_helem[1][2] == 1060);
};

View File

@@ -0,0 +1,212 @@
// alias_idx_family_test — #5 alias arc F2a batch 1 (task #60 + #79 init-store
// rider): wwstage INDEX / SLICE / FOR-RANGE / LITERAL-INIT over an alias-NAMED
// base type, migrated from test/wcc/944_alias_idx_family_run.c (#5-C3). The
// tnode-keyed cgen walks saw only the N_TNAME leaf — esz fell to the
// 1-sentinel and the base classified as a POINTER (MOVQ + no IMULQ): SEGV on
// index/range, silent-wrong on slice, alias-[N]u32 literal-init stride-skew
// (#79). cstage reads everything off the chased stamped type and is the
// runtime-correct reference; the fix re-keys the ww sites off tichase'd
// tinfos and every row graduates to byte-id (ww aligned UP).
//
// Values exceed 255 so an esz=1 byte-load cannot pass by little-endian
// prefix-luck; readbacks assert the LAST element. The C driver ran each row
// on both stages + asserted cs==ww exit; here the cstage run is test-lang (T1)
// and the byte-id is test-lang-byteid (T2). The fwd-ref rows' decl-order
// dimension is subsumed by module-level resolution (already order-independent).
//
// Deliberately NOT pinned (g-fold #77/#78): any DIRECT alias-typed global
// ARRAY row (ww link-ERR / cs silent-wrong) — m7c_global2d's alias is on the
// ELEMENT and gslice_alias is a global alias SLICE, both of which resolve.
package alias_idx_family_test;
type arr = [4]int;
type arr2 = arr;
type sl = []int;
type sl2 = sl;
type a4 = [4]u32;
type a6 = [6]u32;
type arrk = [1024]int;
type slk = []int;
type slk2 = slk;
type row = [3]int;
let g_2d: [2]row = [[10: int, 20: int, 30: int], [40: int, 50: int, 60: int]];
let g_slice: sl = [1000: int, 2000: int, 3000: int];
@test fn idx0_ctl() void = {
let a: [4]int = [1000: int, 2000: int, 3000: int, 4000: int];
assert(a[3] == 4000);
a[3] = 9999;
assert(a[3] == 9999);
};
@test fn idx1_alias() void = {
let a: arr = [1000: int, 2000: int, 3000: int, 4000: int];
assert(a[2] == 3000);
assert(a[3] == 4000);
a[3] = 8888;
assert(a[3] == 8888);
};
@test fn idx2_2level() void = {
let a: arr2 = [1000: int, 2000: int, 3000: int, 4000: int];
assert(a[2] == 3000);
a[1] = 9999;
assert(a[1] == 9999);
assert(a[3] == 4000);
};
@test fn idx_fwdref() void = {
let a: arr2 = [1000: int, 2000: int, 3000: int, 4000: int];
assert(a[3] == 4000);
a[3] += 500;
assert(a[3] == 4500);
};
// #79: narrow-elem alias literal-init — pre-fix the per-element store rode the
// esz=8 sentinel + MOVQ over a stride-4 slot (saved-BP/RIP smash); LAST read.
@test fn init_u32_alias() void = {
let a: a4 = [1: u32, 2: u32, 3: u32, 4: u32];
assert(a[3] == 4);
assert(a[0] == 1);
};
@test fn initrep_u32_alias() void = {
let a: a6 = [7: u32...];
assert(a[5] == 7);
assert(a[0] == 7);
};
// uninit alias array + per-index loop fill; pins the bare-let classify (no
// composite zero-fill, cstage-identical).
@test fn loopfill_1024() void = {
let a: arrk;
let i: int = 0;
for (i < 1024) {
a[i] = i * 3 + 1000;
i += 1;
};
assert(a[1023] == 1023 * 3 + 1000);
};
@test fn slice0_ctl() void = {
let a: [4]int = [1000: int, 2000: int, 3000: int, 4000: int];
let s: []int = a[1:3];
assert(s.len == 2);
assert(s[1] == 3000);
};
@test fn slice1_alias() void = {
let a: arr = [1000: int, 2000: int, 3000: int, 4000: int];
let s: sl = a[1:3];
assert(s.len == 2);
assert(s[0] == 2000);
s[1] = 7777;
assert(a[2] == 7777);
};
@test fn slice2_2level() void = {
let a: [4]int = [1000: int, 2000: int, 3000: int, 4000: int];
let s: sl2 = a[1:3];
assert(s.len == 2);
assert(s[0] == 2000);
s[1] = 7777;
assert(a[2] == 7777);
assert(s[1] == 7777);
let r: sl = s[0:2];
assert(r.len == 2);
assert(r[1] == 7777);
};
// 1000 elements, values 300..7293: an esz=1 byte load cannot land on the right
// word; LAST-elem readback breaks prefix-luck. Also pins alias default-hi
// (a[2:]), .cap via the chased cgbasecap leg, and range over the sub-slice.
@test fn slice1big() void = {
let a: [1000]int;
let i: int = 0;
for (i < 1000) {
a[i] = i * 7 + 300;
i += 1;
};
let s: slk = a[1:1000];
assert(s.len == 999);
assert(s[998] == 999 * 7 + 300);
s[998] = 123456;
assert(a[999] == 123456);
let t: slk2 = a[2:];
assert(t.len == 998);
assert(t.cap == 998);
assert(t[997] == 123456);
let cnt: int = 0;
for (let x .. t) { cnt = cnt + 1; assert(x >= 0); };
assert(cnt == 998);
};
@test fn slice_fwdref() void = {
let a: arr2 = [1000: int, 2000: int, 3000: int, 4000: int];
let s: sl2 = a[1:3];
assert(s[1] == 3000);
s[1] *= 3;
assert(a[2] == 9000);
};
@test fn range0_ctl() void = {
let a: [4]int = [1: int, 2: int, 3: int, 4: int];
let sum: int = 0;
for (let x .. a) { sum = sum + x; };
assert(sum == 10);
};
@test fn range1_alias() void = {
let a: arr = [1000: int, 2000: int, 3000: int, 4000: int];
let sum: int = 0;
for (let x .. a) { sum = sum + x; };
assert(sum == 10000);
};
@test fn range2_2level() void = {
let a: arr2 = [1000: int, 2000: int, 3000: int, 4000: int];
let sum: int = 0;
for (let x .. a) { sum = sum + x; };
assert(sum == 10000);
};
@test fn range_slicealias() void = {
let a: [4]int = [1000: int, 2000: int, 3000: int, 4000: int];
let t: sl = a[0:4];
let sum: int = 0;
for (let x .. t) { sum = sum + x; };
assert(sum == 10000);
};
// m7c: the BASE is a plain [2]row global — the alias sits on the ELEMENT
// (row = [3]int). elemisarrayc's node walk can't see through the element's
// N_TNAME, so g[0] loaded a VALUE where the sub-array ADDRESS was needed.
@test fn m7c_global2d() void = {
assert(g_2d[0][0] == 10);
assert(g_2d[1][2] == 60);
};
// GLOBAL alias-typed SLICE: DATA emit + .len + indexed read all resolve.
@test fn gslice_alias() void = {
assert(g_slice.len == 3);
assert(g_slice[2] == 3000);
};
// slice-of-alias-array as a CALL ARG exercises the pusharg N_SLICE leg, a
// distinct lowering from cgslice; plus inferred-let receive of an alias-base
// slice.
fn sumof(s: []int) int = {
let t: int = 0;
for (let x .. s) { t = t + x; };
return t;
};
@test fn slicearg_alias() void = {
let a: arr2 = [1000: int, 2000: int, 3000: int, 4000: int];
let s = a[1:3];
assert(s.len == 2);
assert(s[1] == 3000);
assert(sumof(a[0:4]) == 10000);
};

View File

@@ -0,0 +1,55 @@
// alias_structlit_init_test — #63: let-init from an alias-NAMED struct
// LITERAL, migrated from test/wcc/944_alias_structlit_init_run.c (#5-C3).
// wwstage's cglet N_STRUCTLIT arm resolved the struct by a BARE
// structlookup(sname): for an alias `type rep2 = rep` only the base `rep` is
// registered, so the lookup returned nil and the field-fill never fired —
// <=8B silently zeroed the slot and DROPPED the literal, >8B loud-bailed.
// The fix routes the arm through structlookupchain (the #92/W2 SSoT), which
// chases the alias chain to the base struct; cstage was always correct via
// type_chase_named, so this is ww-only align-UP. The >24B sret RETURN twin
// (cgenstmt:1250) had no scalar-default catch and was silently wrong —
// reviewer-63 routed it through structlookupchain too (sret_return_alias32).
//
// The C driver ran each row on both stages + asserted cs==ww exit; here the
// cstage run is test-lang (T1) and the byte-id is test-lang-byteid (T2).
package alias_structlit_init_test;
type rep = struct { id: size };
type rep2 = rep;
type st = struct { a: size, b: size };
type row = st;
type pt2 = struct { a: size, b: size };
type big = struct { a: size, b: size, c: size, d: size };
type biga = big;
fn mk() biga = { return biga{a=1, b=2, c=3, d=4}; };
@test fn letinit_typed() void = {
let r: rep2 = rep2{id=6};
assert(r.id: int == 6);
};
@test fn letinit_untyped() void = {
let r = rep2{id=6};
assert(r.id: int == 6);
};
@test fn letlit_alias16() void = {
let a: row = row{a=3, b=4};
assert((a.a + a.b): int == 7);
};
// control: non-alias 16B let-init — the no-regress guard (the alias hop is
// the trigger).
@test fn control_direct() void = {
let x: pt2 = pt2{a=3, b=4};
assert((x.a + x.b): int == 7);
};
// the >24B sret-RETURN twin of the let-init site (cgenstmt:1250): the alias
// field-fill was SKIPPED and the callee returned an uninitialised sret buffer.
@test fn sret_return_alias32() void = {
let r: biga = mk();
assert((r.a + r.b + r.c + r.d): int == 10);
};