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:
20
test/lang/alias_accept_runonly_test.ww
Normal file
20
test/lang/alias_accept_runonly_test.ww
Normal 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);
|
||||
};
|
||||
812
test/lang/alias_accept_test.ww
Normal file
812
test/lang/alias_accept_test.ww
Normal 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);
|
||||
};
|
||||
378
test/lang/alias_cgen_b5_test.ww
Normal file
378
test/lang/alias_cgen_b5_test.ww
Normal 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);
|
||||
};
|
||||
271
test/lang/alias_cgen_b6_test.ww
Normal file
271
test/lang/alias_cgen_b6_test.ww
Normal 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); };
|
||||
};
|
||||
};
|
||||
37
test/lang/alias_decl_order_size_runonly_test.ww
Normal file
37
test/lang/alias_decl_order_size_runonly_test.ww
Normal 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);
|
||||
};
|
||||
139
test/lang/alias_decl_order_size_test.ww
Normal file
139
test/lang/alias_decl_order_size_test.ww
Normal 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);
|
||||
};
|
||||
95
test/lang/alias_emit_b7_test.ww
Normal file
95
test/lang/alias_emit_b7_test.ww
Normal 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);
|
||||
};
|
||||
179
test/lang/alias_global_decl_test.ww
Normal file
179
test/lang/alias_global_decl_test.ww
Normal 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);
|
||||
};
|
||||
212
test/lang/alias_idx_family_test.ww
Normal file
212
test/lang/alias_idx_family_test.ww
Normal 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);
|
||||
};
|
||||
55
test/lang/alias_structlit_init_test.ww
Normal file
55
test/lang/alias_structlit_init_test.ww
Normal 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);
|
||||
};
|
||||
Reference in New Issue
Block a user