// dotbase_addr_slice_test — the array-field-base-address family: addr-of + // slice of a struct's `[N]T` FIELD (#252), the CHAINED-base close-out (#253), // the signed-narrow N_DOT-base index load (#255), the call-arg consumption // axis (#257), the tagged-element store/read/return cluster (#259/#261/#263), // the aggregate deref-rhs let-init (#265), addressable-rhs let-init and // def-global copy (#268), and aggregate-arg-from-any-source (#271) axes, the // array return-by-value ABI (#267), nested-array outer stride (#270-2), // element store (#270-1) + array-literal element store (#270-1c), and the // aggregate index-base copy (#270-3a). Migrated from // test/wcc/949_dotbase_addr_slice_run.c. // // The shared root: taking `&x.o[i]` / slicing `x.o[lo:hi]` / indexing a // chained `o.p.m[i]` of an `[N]T`-typed FIELD must compute the field's // ADDRESS (LEAQ), not auto-deref its first 8 bytes AS a pointer (MOVL) — // garbage base -> segfault. cg_dotbase_addr/dotbaseaddr (+ the dotchain spine // for chained inners) close the whole family; every op (index r/w, addr-of, // slice, compound, store, call-arg, copy) routes through the one helper. // cs==ww broken IDENTICALLY pre-fix (gate-blind, pure correctness), so the // .s is byte-identical post-fix and the T2 byteid gate is the rule-10 net; // these behavioral @tests are the runtime net. PRIMITIVE-only asserts (read // back the value through the &-derived pointer / slice; a wrong base or a // dropped header/word yields a wrong readback) — no fmt/strconv anywhere. // // The chained VALUE-container arm (`o.i.m`, value nested struct) and the // value-nested-struct let-init copy rows are byteid=0 (#254: bare-let // zero-init extra MOVQ $0 + global DATAW over-emit) and live in the sibling // dotbase_addr_slice_runonly_test.ww, excluded from T2 by the _runonly_ // suffix. package dotbase_addr_slice_test; type eu8 = struct { o: [4]u8 }; type ei32 = struct { o: [4]i32 }; type ei16 = struct { o: [4]i16 }; type ei8 = struct { o: [4]i8 }; type cinner = struct { m: [4]u8 }; // also the ctrl `e` shape type couter = struct { p: *cinner }; type cinneri = struct { m: [4]i32 }; type couteri = struct { p: *cinneri }; @test fn addr_local_u8() void = { let x: eu8; x.o[1] = 66u8; let p: *u8 = &x.o[1]; assert((*p): i32 == 66i32); }; fn rd_addr_ptr_u8(x: *eu8) u8 = { let p: *u8 = &x.o[2]; return *p; }; @test fn addr_ptr_u8() void = { let x: eu8; x.o[2] = 77u8; assert(rd_addr_ptr_u8(&x): i32 == 77i32); }; @test fn addr_i32() void = { let x: ei32; x.o[2] = 88; let p: *i32 = &x.o[2]; assert(*p == 88i32); }; @test fn slice_u8_expl() void = { let x: eu8; x.o[1] = 66u8; let s: []u8 = x.o[1:4]; assert(len(s): i32 == 3i32); assert(s[0]: i32 == 66i32); }; @test fn slice_u8_dflthi() void = { let x: eu8; x.o[1] = 66u8; let s: []u8 = x.o[1:]; assert(len(s): i32 == 3i32); assert(s[0]: i32 == 66i32); }; fn sl_slice_ptr_u8(x: *eu8) u8 = { let s: []u8 = x.o[1:4]; return s[0]; }; @test fn slice_ptr_u8() void = { let x: eu8; x.o[1] = 66u8; assert(sl_slice_ptr_u8(&x): i32 == 66i32); }; @test fn slice_i32_expl() void = { let x: ei32; x.o[1] = 99; x.o[2] = 88; let s: []i32 = x.o[1:3]; assert(len(s): i32 == 2i32); assert(s[1] == 88i32); }; @test fn slice_i32_dflt() void = { let x: ei32; x.o[3] = 55; let s: []i32 = x.o[1:]; assert(len(s): i32 == 3i32); assert(s[2] == 55i32); }; @test fn control_bare() void = { let a: [4]u8; a[2] = 44u8; let p: *u8 = &a[1]; *p = 33u8; let s: []u8 = a[1:4]; assert(s[0]: i32 == 33i32); // the &a[1] write landed assert(s[1]: i32 == 44i32); }; @test fn chain_ptr_rd() void = { let a: cinner; a.m[1] = 66u8; let o: couter; o.p = &a; assert(o.p.m[1]: i32 == 66i32); }; @test fn chain_ptr_wr() void = { let a: cinner; let o: couter; o.p = &a; o.p.m[2] = 77u8; assert(a.m[2]: i32 == 77i32); }; @test fn chain_ptr_addr() void = { let a: cinner; a.m[2] = 55u8; let o: couter; o.p = &a; let q: *u8 = &o.p.m[2]; assert((*q): i32 == 55i32); }; @test fn chain_ptr_sl_e() void = { let a: cinner; a.m[1] = 66u8; let o: couter; o.p = &a; let s: []u8 = o.p.m[1:4]; assert(len(s): i32 == 3i32); assert(s[0]: i32 == 66i32); }; @test fn chain_ptr_sl_d() void = { let a: cinner; a.m[1] = 66u8; let o: couter; o.p = &a; let s: []u8 = o.p.m[1:]; assert(len(s): i32 == 3i32); assert(s[0]: i32 == 66i32); }; @test fn chain_ptr_comp() void = { let a: cinner; a.m[1] = 60u8; let o: couter; o.p = &a; o.p.m[1] += 6u8; assert(o.p.m[1]: i32 == 66i32); }; type cmid = struct { b: *cinner }; type ctop = struct { a: cmid }; @test fn chain_deep_lf() void = { let z: cinner; z.m[1] = 66u8; let o: ctop; o.a.b = &z; assert(o.a.b.m[1]: i32 == 66i32); }; type camid = struct { q: *cinner }; type cotop = struct { p: *camid }; @test fn chain_triple() void = { let z: cinner; z.m[1] = 66u8; let aa: camid; aa.q = &z; let o: cotop; o.p = &aa; assert(o.p.q.m[1]: i32 == 66i32); }; @test fn chain_tri_comp() void = { let z: cinner; z.m[1] = 60u8; let aa: camid; aa.q = &z; let o: cotop; o.p = &aa; o.p.q.m[1] += 6u8; assert(o.p.q.m[1]: i32 == 66i32); }; @test fn chain_i32_addr() void = { let a: cinneri; a.m[2] = 88; let o: couteri; o.p = &a; let q: *i32 = &o.p.m[2]; assert(*q == 88i32); }; @test fn chain_i32_slice() void = { let a: cinneri; a.m[1] = 99; a.m[2] = 88; let o: couteri; o.p = &a; let s: []i32 = o.p.m[1:3]; assert(len(s): i32 == 2i32); assert(s[1] == 88i32); }; fn rd_ctrl_ptr_rd(p: *cinner) u8 = { return p.m[1]; }; @test fn ctrl_ptr_rd() void = { let x: cinner; x.m[1] = 66u8; assert(rd_ctrl_ptr_rd(&x): i32 == 66i32); }; @test fn ctrl_local_rd() void = { let x: cinner; x.m[1] = 66u8; assert(x.m[1]: i32 == 66i32); }; @test fn nload_i32() void = { let x: ei32; x.o[2] = -5; let v: i32 = x.o[2]; assert(v == -5i32); }; @test fn nload_i16() void = { let x: ei16; x.o[2] = -5i16; let v: i16 = x.o[2]; assert(v: i32 == -5i32); }; @test fn nload_i8() void = { let x: ei8; x.o[2] = -5i8; let v: i8 = x.o[2]; assert(v: i32 == -5i32); }; fn rd_callarg_u8(b: []u8) i32 = { return b[0]: i32; }; @test fn callarg_u8() void = { let x: eu8; x.o[1] = 66u8; assert(rd_callarg_u8(x.o[1:4]) == 66i32); }; fn rd_callarg_i32(b: []i32) i32 = { return b[0]; }; @test fn callarg_i32() void = { let x: ei32; x.o[1] = 88; assert(rd_callarg_i32(x.o[1:3]) == 88i32); }; fn rd_callarg_ptr_u8(b: []u8) i32 = { return b[0]: i32; }; fn f_callarg_ptr_u8(p: *eu8) i32 = { return rd_callarg_ptr_u8(p.o[1:4]); }; @test fn callarg_ptr_u8() void = { let x: eu8; x.o[1] = 66u8; assert(f_callarg_ptr_u8(&x) == 66i32); }; fn rd_callarg_chain(b: []u8) i32 = { return b[0]: i32; }; @test fn callarg_chain() void = { let a: cinner; a.m[1] = 66u8; let o: couter; o.p = &a; assert(rd_callarg_chain(o.p.m[1:4]) == 66i32); }; fn rd_callarg_ctrl_local(b: []u8) i32 = { return b[0]: i32; }; @test fn callarg_ctrl_local() void = { let x: eu8; x.o[1] = 66u8; let sl: []u8 = x.o[1:4]; assert(rd_callarg_ctrl_local(sl) == 66i32); }; fn rd_callarg_ctrl_arr(b: []u8) i32 = { return b[0]: i32; }; @test fn callarg_ctrl_arr() void = { let a: [4]u8; a[1] = 66u8; assert(rd_callarg_ctrl_arr(a[1:4]) == 66i32); }; type wsf = struct { v: []i32 }; fn rd_callarg_slicefield(s: []i32) i32 = { return s[0]; }; @test fn callarg_slicefield() void = { let backing: [4]i32; backing[1] = 88; let q: wsf; q.v = backing[0:4]; assert(rd_callarg_slicefield(q.v[1:3]) == 88i32); }; type wstr = struct { v: str }; fn rd_callarg_strfield(s: str) i32 = { return len(s): i32; }; @test fn callarg_strfield() void = { let q: wstr; q.v = "hello"; assert(rd_callarg_strfield(q.v[1:4]) == 3i32); }; type etag = struct { o: [4](i32 | void) }; type etagnull = struct { o: [4](*i32 | void) }; type mtag2d = struct { g: [2][2](i32 | void) }; @test fn tagged_store_own() void = { let x: etag; x.o[1] = 66; let v: (i32 | void) = x.o[1]; let r: i32 = match (v) { case let n: i32 => yield n; case void => yield 0: i32; }; assert(r == 66i32); }; fn wr_tagged_store_ptr(x: *etag) void = { x.o[2] = 77; }; @test fn tagged_store_ptr() void = { let x: etag; wr_tagged_store_ptr(&x); let v: (i32 | void) = x.o[2]; let r: i32 = match (v) { case let n: i32 => yield n; case void => yield 0: i32; }; assert(r == 77i32); }; @test fn tagged_store_own_rd() void = { let x: etag; x.o[1] = 66; let v: (i32 | void) = x.o[1]; let r: i32 = match (v) { case let n: i32 => yield n; case void => yield 0: i32; }; assert(r == 66i32); }; fn wr_tagged_store_ptr_rd(x: *etag) void = { x.o[2] = 77; }; @test fn tagged_store_ptr_rd() void = { let x: etag; wr_tagged_store_ptr_rd(&x); let v: (i32 | void) = x.o[2]; let r: i32 = match (v) { case let n: i32 => yield n; case void => yield 0: i32; }; assert(r == 77i32); }; @test fn tagged_rd_void() void = { let x: etag; x.o[1] = void; let v: (i32 | void) = x.o[1]; let r: i32 = match (v) { case let n: i32 => yield 99: i32; case void => yield 1: i32; }; assert(r == 1i32); }; fn take_tagged_callarg_i32(v: (i32 | void)) i32 = { return match (v) { case let n: i32 => yield n; case void => yield 1: i32; }; }; @test fn tagged_callarg_i32() void = { let x: etag; x.o[2] = 55; assert(take_tagged_callarg_i32(x.o[2]) == 55i32); }; fn take_tagged_callarg_void(v: (i32 | void)) i32 = { return match (v) { case let n: i32 => yield 99: i32; case void => yield 1: i32; }; }; @test fn tagged_callarg_void() void = { let x: etag; x.o[2] = void; assert(take_tagged_callarg_void(x.o[2]) == 1i32); }; fn ret_tagged_return_i32(x: *etag) (i32 | void) = { return x.o[1]; }; @test fn tagged_return_i32() void = { let x: etag; x.o[1] = 88; let v: (i32 | void) = ret_tagged_return_i32(&x); let r: i32 = match (v) { case let n: i32 => yield n; case void => yield 1: i32; }; assert(r == 88i32); }; fn ret_tagged_return_void(x: *etag) (i32 | void) = { return x.o[1]; }; @test fn tagged_return_void() void = { let x: etag; x.o[1] = void; let v: (i32 | void) = ret_tagged_return_void(&x); let r: i32 = match (v) { case let n: i32 => yield 99: i32; case void => yield 1: i32; }; assert(r == 1i32); }; @test fn tagged_chained_i32() void = { let y: mtag2d; y.g[1][1] = 44; let v: (i32 | void) = y.g[1][1]; let r: i32 = match (v) { case let n: i32 => yield n; case void => yield 1: i32; }; assert(r == 44i32); }; @test fn tagged_chained_void() void = { let y: mtag2d; y.g[1][1] = void; let v: (i32 | void) = y.g[1][1]; let r: i32 = match (v) { case let n: i32 => yield 99: i32; case void => yield 1: i32; }; assert(r == 1i32); }; @test fn tagged_ctrl_bare_rd() void = { let a: [4](i32 | void); a[1] = 33; let v: (i32 | void) = a[1]; let r: i32 = match (v) { case let n: i32 => yield n; case void => yield 1: i32; }; assert(r == 33i32); }; @test fn tagged_null_ptr_rd() void = { let k: i32 = 7; let x: etagnull; x.o[1] = &k; let v: (*i32 | void) = x.o[1]; let r: i32 = match (v) { case let p: *i32 => yield 55: i32; case void => yield 1: i32; }; assert(r == 55i32); }; @test fn tagged_null_void_rd() void = { let x: etagnull; x.o[1] = void; let v: (*i32 | void) = x.o[1]; let r: i32 = match (v) { case let p: *i32 => yield 99: i32; case void => yield 1: i32; }; assert(r == 1i32); }; fn g_tagged_ident_ret_i32() (i32 | void) = { let v: (i32 | void) = 7i32; return v; }; @test fn tagged_ident_ret_i32() void = { let r: i32 = match (g_tagged_ident_ret_i32()) { case let n: i32 => yield n; case void => yield 1: i32; }; assert(r == 7i32); }; fn g_tagged_ident_ret_void() (i32 | void) = { let v: (i32 | void) = void; return v; }; @test fn tagged_ident_ret_void() void = { let r: i32 = match (g_tagged_ident_ret_void()) { case let n: i32 => yield 99: i32; case void => yield 1: i32; }; assert(r == 1i32); }; fn inner_tagged_call_ret_ctrl() (i32 | void) = { let v: (i32 | void) = 42i32; return v; }; fn outer_tagged_call_ret_ctrl() (i32 | void) = { return inner_tagged_call_ret_ctrl(); }; @test fn tagged_call_ret_ctrl() void = { let r: i32 = match (outer_tagged_call_ret_ctrl()) { case let n: i32 => yield n; case void => yield 1: i32; }; assert(r == 42i32); }; type wtagfield = struct { f: (i32 | void) }; fn dot_tagged_dot_ret_ctrl(x: *wtagfield) (i32 | void) = { return x.f; }; @test fn tagged_dot_ret_ctrl() void = { let x: wtagfield; x.f = 63; let r: i32 = match (dot_tagged_dot_ret_ctrl(&x)) { case let n: i32 => yield n; case void => yield 1: i32; }; assert(r == 63i32); }; type t16 = struct { h: [4]u32 }; type t32 = struct { h: [8]u32 }; @test fn deref_struct16() void = { let s: t16; s.h[0]=10u32; s.h[1]=20u32; s.h[2]=30u32; s.h[3]=40u32; let c: t16 = *(&s); assert((c.h[0]+c.h[1]+c.h[2]+c.h[3]): i32 == 100i32); }; @test fn deref_struct32() void = { let s: t32; s.h[0]=1u32; s.h[1]=2u32; s.h[2]=3u32; s.h[3]=4u32; s.h[4]=5u32; s.h[5]=6u32; s.h[6]=7u32; s.h[7]=8u32; let c: t32 = *(&s); assert((c.h[0]+c.h[1]+c.h[2]+c.h[3] +c.h[4]+c.h[5]+c.h[6]+c.h[7]): i32 == 36i32); }; @test fn deref_ptr32() void = { let s: t32; s.h[0]=1u32; s.h[1]=2u32; s.h[2]=3u32; s.h[3]=4u32; s.h[4]=5u32; s.h[5]=6u32; s.h[6]=7u32; s.h[7]=8u32; let p: *t32 = &s; let c: t32 = *p; assert((c.h[0]+c.h[1]+c.h[2]+c.h[3] +c.h[4]+c.h[5]+c.h[6]+c.h[7]): i32 == 36i32); }; @test fn deref_array16() void = { let s: [4]u32; s[0]=5u32; s[1]=6u32; s[2]=7u32; s[3]=8u32; let c: [4]u32 = *(&s); assert((c[0]+c[1]+c[2]+c[3]): i32 == 26i32); }; @test fn deref_tail12() void = { let s: [3]u32; s[0]=7u32; s[1]=8u32; s[2]=9u32; let c: [3]u32 = *(&s); assert((c[0]+c[1]+c[2]): i32 == 24i32); }; @test fn deref_tail11() void = { let s: [11]u8; s[0]=1u8; s[1]=2u8; s[2]=3u8; s[3]=4u8; s[4]=5u8; s[5]=6u8; s[6]=7u8; s[7]=8u8; s[8]=9u8; s[9]=10u8; s[10]=11u8; let c: [11]u8 = *(&s); assert((c[0]+c[1]+c[2]+c[3]+c[4]+c[5] +c[6]+c[7]+c[8]+c[9]+c[10]): i32 == 66i32); }; @test fn ai_array16() void = { let s: [4]u32; s[0]=11u32; s[1]=22u32; s[2]=33u32; s[3]=44u32; let c: [4]u32 = s; assert((c[0]+c[1]+c[2]+c[3]): i32 == 110i32); }; @test fn ai_array32() void = { let s: [8]u32; s[0]=1u32; s[1]=2u32; s[2]=3u32; s[3]=4u32; s[4]=5u32; s[5]=6u32; s[6]=7u32; s[7]=8u32; let c: [8]u32 = s; assert((c[0]+c[1]+c[2]+c[3]+c[4]+c[5]+c[6]+c[7]): i32 == 36i32); }; @test fn ai_tail12() void = { let s: [3]u32; s[0]=7u32; s[1]=8u32; s[2]=9u32; let c: [3]u32 = s; assert((c[0]+c[1]+c[2]): i32 == 24i32); }; @test fn ai_tail11() void = { let s: [11]u8; s[0]=1u8; s[1]=2u8; s[2]=3u8; s[3]=4u8; s[4]=5u8; s[5]=6u8; s[6]=7u8; s[7]=8u8; s[8]=9u8; s[9]=10u8; s[10]=11u8; let c: [11]u8 = s; assert((c[0]+c[1]+c[2]+c[3]+c[4]+c[5] +c[6]+c[7]+c[8]+c[9]+c[10]): i32 == 66i32); }; type dinner16 = struct { m: [4]u32 }; type douter16 = struct { i: dinner16 }; @test fn dot_struct16() void = { let o: douter16; o.i.m[0]=10u32; o.i.m[1]=20u32; o.i.m[2]=30u32; o.i.m[3]=40u32; let c: dinner16 = o.i; assert((c.m[0]+c.m[1]+c.m[2]+c.m[3]): i32 == 100i32); }; type douter32 = struct { o: [8]u32 }; @test fn dot_arr32() void = { let x: douter32; x.o[0]=1u32; x.o[1]=2u32; x.o[2]=3u32; x.o[3]=4u32; x.o[4]=5u32; x.o[5]=6u32; x.o[6]=7u32; x.o[7]=8u32; let c: [8]u32 = x.o; assert((c[0]+c[1]+c[2]+c[3]+c[4]+c[5]+c[6]+c[7]): i32 == 36i32); }; type dinner11 = struct { m: [11]u8 }; type douter11 = struct { i: dinner11 }; @test fn dot_tail11() void = { let o: douter11; o.i.m[0]=1u8; o.i.m[1]=2u8; o.i.m[2]=3u8; o.i.m[3]=4u8; o.i.m[4]=5u8; o.i.m[5]=6u8; o.i.m[6]=7u8; o.i.m[7]=8u8; o.i.m[8]=9u8; o.i.m[9]=10u8; o.i.m[10]=11u8; let c: dinner11 = o.i; assert((c.m[0]+c.m[1]+c.m[2]+c.m[3]+c.m[4]+c.m[5] +c.m[6]+c.m[7]+c.m[8]+c.m[9]+c.m[10]): i32 == 66i32); }; @test fn idx_struct16() void = { let a: [2]dinner16; let p: *dinner16 = &a[1]; p.m[0]=10u32; p.m[1]=20u32; p.m[2]=30u32; p.m[3]=40u32; let c: dinner16 = a[1]; assert((c.m[0]+c.m[1]+c.m[2]+c.m[3]): i32 == 100i32); }; type dinner32 = struct { m: [8]u32 }; @test fn idx_struct32() void = { let a: [2]dinner32; let p: *dinner32 = &a[1]; p.m[0]=1u32; p.m[1]=2u32; p.m[2]=3u32; p.m[3]=4u32; p.m[4]=5u32; p.m[5]=6u32; p.m[6]=7u32; p.m[7]=8u32; let c: dinner32 = a[1]; assert((c.m[0]+c.m[1]+c.m[2]+c.m[3] +c.m[4]+c.m[5]+c.m[6]+c.m[7]): i32 == 36i32); }; def Gad: [4]u32 = [11u32, 22u32, 33u32, 44u32]; @test fn arraydef_global() void = { let c: [4]u32 = Gad; assert((c[0]+c[1]+c[2]+c[3]): i32 == 110i32); }; type gT = struct { a: u32, b: u32, c: u32, d: u32 }; def Gsd: gT = gT { a = 10u32, b = 20u32, c = 30u32, d = 40u32 }; @test fn structdef_global() void = { let c: gT = Gsd; assert((c.a+c.b+c.c+c.d): i32 == 100i32); }; fn mk_ret_arr_u32_8() [2]u32 = { let a: [2]u32; a[0]=3u32; a[1]=4u32; return a; }; @test fn ret_arr_u32_8() void = { let c = mk_ret_arr_u32_8(); assert((c[0]+c[1]): i32 == 7i32); }; fn mk_ret_arr_u32_16() [4]u32 = { let a: [4]u32; a[0]=1u32;a[1]=2u32;a[2]=3u32;a[3]=4u32; return a; }; @test fn ret_arr_u32_16() void = { let c = mk_ret_arr_u32_16(); assert((c[0]+c[1]+c[2]+c[3]): i32 == 10i32); }; fn mk_ret_arr_u32_24() [6]u32 = { let a: [6]u32; a[0]=1u32;a[1]=2u32;a[2]=3u32;a[3]=4u32;a[4]=5u32;a[5]=6u32; return a; }; @test fn ret_arr_u32_24() void = { let c = mk_ret_arr_u32_24(); assert((c[0]+c[1]+c[2]+c[3]+c[4]+c[5]): i32 == 21i32); }; fn mk_ret_arr_u32_32_sret() [8]u32 = { let a: [8]u32; a[0]=1u32;a[1]=2u32;a[2]=3u32;a[3]=4u32;a[4]=5u32;a[5]=6u32;a[6]=7u32;a[7]=8u32; return a; }; @test fn ret_arr_u32_32_sret() void = { let c = mk_ret_arr_u32_32_sret(); assert((c[0]+c[1]+c[2]+c[3]+c[4]+c[5]+c[6]+c[7]): i32 == 36i32); }; fn mk_ret_arr_u8_4() [4]u8 = { let a: [4]u8; a[0]=10u8;a[1]=20u8;a[2]=30u8;a[3]=40u8; return a; }; @test fn ret_arr_u8_4() void = { let c = mk_ret_arr_u8_4(); assert((c[0]+c[1]+c[2]+c[3]): i32 == 100i32); }; fn mk_ret_arr_u8_32_sret() [32]u8 = { let a: [32]u8; a[0]=50u8;a[15]=30u8;a[31]=40u8; return a; }; @test fn ret_arr_u8_32_sret() void = { let c = mk_ret_arr_u8_32_sret(); assert((c[0]+c[15]+c[31]): i32 == 120i32); }; fn mk_ret_arr_assign_16() [4]u32 = { let a: [4]u32; a[0]=1u32;a[1]=2u32;a[2]=3u32;a[3]=4u32; return a; }; @test fn ret_arr_assign_16() void = { let c: [4]u32; c = mk_ret_arr_assign_16(); assert((c[0]+c[1]+c[2]+c[3]): i32 == 10i32); }; fn mk_ret_arr_assign_32_sret() [8]u32 = { let a: [8]u32; a[0]=1u32;a[7]=8u32; return a; }; @test fn ret_arr_assign_32_sret() void = { let c: [8]u32; c = mk_ret_arr_assign_32_sret(); assert((c[0]+c[7]): i32 == 9i32); }; fn mk_ret_arr_fwd_16() [4]u32 = { let a: [4]u32; a[0]=1u32;a[1]=2u32;a[2]=3u32;a[3]=4u32; return a; }; fn fwd_ret_arr_fwd_16() [4]u32 = { return mk_ret_arr_fwd_16(); }; @test fn ret_arr_fwd_16() void = { let c = fwd_ret_arr_fwd_16(); assert((c[0]+c[1]+c[2]+c[3]): i32 == 10i32); }; fn mk_ret_arr_fwd_32_sret() [8]u32 = { let a: [8]u32; a[0]=1u32;a[7]=8u32; return a; }; fn fwd_ret_arr_fwd_32_sret() [8]u32 = { return mk_ret_arr_fwd_32_sret(); }; @test fn ret_arr_fwd_32_sret() void = { let c = fwd_ret_arr_fwd_32_sret(); assert((c[0]+c[7]): i32 == 9i32); }; type sret3 = struct { a: u32, b: u32, c: u32 }; fn mk_ctrl_struct_ret() sret3 = { let s: sret3; s.a=1u32;s.b=2u32;s.c=3u32; return s; }; @test fn ctrl_struct_ret() void = { let v = mk_ctrl_struct_ret(); assert((v.a+v.b+v.c): i32 == 6i32); }; @test fn nest2d_u32() void = { let a: [2][3]u32; a[0][1] = 11u32; a[1][1] = 22u32; a[1][2] = 33u32; assert((a[0][1] + a[1][1] + a[1][2]): i32 == 66i32); }; @test fn nest2d_u8() void = { let a: [2][3]u8; a[0][2] = 10u8; a[1][0] = 20u8; a[1][2] = 30u8; assert((a[0][2] + a[1][0] + a[1][2]): i32 == 60i32); }; @test fn nest2d_i32() void = { let a: [2][3]i32; a[0][1] = 40; a[1][1] = 88; assert((a[1][1] - a[0][1]): i32 == 48i32); }; type efinner = struct { m: [4]u32 }; @test fn elemfield_store() void = { let a: [3]efinner; a[0].m[1] = 5u32; a[2].m[3] = 7u32; a[2].m[0] = 9u32; assert((a[0].m[1] + a[2].m[3] + a[2].m[0]): i32 == 21i32); }; @test fn elem_struct_store() void = { let arr: [3]gT; let v: gT; v.a=10u32; v.b=20u32; v.c=30u32; v.d=40u32; arr[2] = v; assert((arr[2].a + arr[2].b + arr[2].c + arr[2].d): i32 == 100i32); }; @test fn elem_arr_store() void = { let arr: [2][4]u32; let s: [4]u32; s[0]=1u32; s[1]=2u32; s[2]=3u32; s[3]=4u32; arr[1] = s; assert((arr[1][0]+arr[1][1]+arr[1][2]+arr[1][3]): i32 == 10i32); }; type boxprim = struct { arr: [2][4]u32 }; @test fn letcopy_dot_prim() void = { let s: [4]u32; s[0]=1u32; s[1]=2u32; s[2]=3u32; s[3]=4u32; let x: boxprim; x.arr[1] = s; let c: [4]u32 = x.arr[1]; assert((c[0]+c[1]+c[2]+c[3]): i32 == 10i32); }; @test fn letcopy_nest_prim() void = { let a: [2][2][4]u32; let s: [4]u32; s[0]=2u32; s[1]=4u32; s[2]=6u32; s[3]=8u32; a[1][0] = s; let c: [4]u32 = a[1][0]; assert((c[0]+c[1]+c[2]+c[3]): i32 == 20i32); }; @test fn letcopy_subarr() void = { let a: [2][3]u32; a[1][0] = 5u32; a[1][1] = 6u32; a[1][2] = 7u32; let c: [3]u32 = a[1]; assert((c[0] + c[1] + c[2]): i32 == 18i32); }; type inner2 = struct { a: u32, b: u32 }; @test fn arrlit_structlit() void = { let x: [2]inner2 = [inner2{a=1u32,b=2u32}, inner2{a=3u32,b=4u32}]; assert((x[0].a + x[0].b + x[1].a + x[1].b): i32 == 10i32); }; @test fn arrlit_structident() void = { let p: inner2; p.a = 7u32; p.b = 8u32; let q: inner2; q.a = 1u32; q.b = 2u32; let x: [2]inner2 = [p, q]; assert((x[0].a + x[0].b + x[1].a + x[1].b): i32 == 18i32); }; type argt16 = struct { x: i64, y: i64 }; type argo16 = struct { f: argt16 }; fn mk_arg_struct16_call() argt16 = { let a: argt16; a.x=3i64; a.y=7i64; return a; }; fn sum_arg_struct16_call(b: argt16) i64 = { return b.x + b.y; }; @test fn arg_struct16_call() void = { assert(sum_arg_struct16_call(mk_arg_struct16_call()): i32 == 10i32); }; fn sum_arg_struct16_dot(b: argt16) i64 = { return b.x + b.y; }; @test fn arg_struct16_dot() void = { let q: argo16; q.f.x=3i64; q.f.y=7i64; assert(sum_arg_struct16_dot(q.f): i32 == 10i32); }; fn sum_arg_struct16_idx(b: argt16) i64 = { return b.x + b.y; }; @test fn arg_struct16_idx() void = { let a: [2]argt16; a[1].x=3i64; a[1].y=7i64; assert(sum_arg_struct16_idx(a[1]): i32 == 10i32); }; fn sum_arg_struct16_deref(b: argt16) i64 = { return b.x + b.y; }; @test fn arg_struct16_deref() void = { let v: argt16; v.x=3i64; v.y=7i64; let p: *argt16 = &v; assert(sum_arg_struct16_deref(*p): i32 == 10i32); }; fn sum_arg_struct16_ident(b: argt16) i64 = { return b.x + b.y; }; @test fn arg_struct16_ident() void = { let v: argt16; v.x=3i64; v.y=7i64; assert(sum_arg_struct16_ident(v): i32 == 10i32); }; fn mk_arg_arr16_call() [4]u32 = { let a: [4]u32; a[0]=1u32;a[1]=2u32;a[2]=3u32;a[3]=4u32; return a; }; fn sum_arg_arr16_call(b: [4]u32) i32 = { return (b[0]+b[1]+b[2]+b[3]): i32; }; @test fn arg_arr16_call() void = { assert(sum_arg_arr16_call(mk_arg_arr16_call()) == 10i32); }; type argof = struct { f: [4]u32 }; fn sum_arg_arr16_dot(b: [4]u32) i32 = { return (b[0]+b[1]+b[2]+b[3]): i32; }; @test fn arg_arr16_dot() void = { let q: argof; q.f[0]=1u32; q.f[1]=2u32; q.f[2]=3u32; q.f[3]=4u32; assert(sum_arg_arr16_dot(q.f) == 10i32); }; fn sum_arg_arr16_idx(b: [4]u32) i32 = { return (b[0]+b[1]+b[2]+b[3]): i32; }; @test fn arg_arr16_idx() void = { let a: [2][4]u32; a[1][0]=1u32; a[1][1]=2u32; a[1][2]=3u32; a[1][3]=4u32; assert(sum_arg_arr16_idx(a[1]) == 10i32); }; fn sum_arg_arr16_deref(b: [4]u32) i32 = { return (b[0]+b[1]+b[2]+b[3]): i32; }; @test fn arg_arr16_deref() void = { let v: [4]u32; v[0]=1u32; v[1]=2u32; v[2]=3u32; v[3]=4u32; let p: *[4]u32 = &v; assert(sum_arg_arr16_deref(*p) == 10i32); }; fn sum_arg_arr16_ident(b: [4]u32) i32 = { return (b[0]+b[1]+b[2]+b[3]): i32; }; @test fn arg_arr16_ident() void = { let v: [4]u32; v[0]=1u32; v[1]=2u32; v[2]=3u32; v[3]=4u32; assert(sum_arg_arr16_ident(v) == 10i32); }; type argo32 = struct { f: t32 }; fn mk_arg_struct32_call() t32 = { let a: t32; a.h[0]=1u32;a.h[1]=2u32;a.h[2]=3u32;a.h[3]=4u32;a.h[4]=5u32;a.h[5]=6u32;a.h[6]=7u32;a.h[7]=8u32; return a; }; fn sum_arg_struct32_call(b: t32) i32 = { return (b.h[0]+b.h[1]+b.h[2]+b.h[3]+b.h[4]+b.h[5]+b.h[6]+b.h[7]): i32; }; @test fn arg_struct32_call() void = { assert(sum_arg_struct32_call(mk_arg_struct32_call()) == 36i32); }; fn sum_arg_struct32_dot(b: t32) i32 = { return (b.h[0]+b.h[1]+b.h[2]+b.h[3]+b.h[4]+b.h[5]+b.h[6]+b.h[7]): i32; }; @test fn arg_struct32_dot() void = { let q: argo32; q.f.h[0]=1u32;q.f.h[1]=2u32;q.f.h[2]=3u32;q.f.h[3]=4u32; q.f.h[4]=5u32;q.f.h[5]=6u32;q.f.h[6]=7u32;q.f.h[7]=8u32; assert(sum_arg_struct32_dot(q.f) == 36i32); }; fn sum_arg_struct32_idx(b: t32) i32 = { return (b.h[0]+b.h[1]+b.h[2]+b.h[3]+b.h[4]+b.h[5]+b.h[6]+b.h[7]): i32; }; @test fn arg_struct32_idx() void = { let a: [2]t32; let p: *t32 = &a[1]; p.h[0]=1u32;p.h[1]=2u32;p.h[2]=3u32;p.h[3]=4u32; p.h[4]=5u32;p.h[5]=6u32;p.h[6]=7u32;p.h[7]=8u32; assert(sum_arg_struct32_idx(a[1]) == 36i32); }; fn sum_arg_struct32_deref(b: t32) i32 = { return (b.h[0]+b.h[1]+b.h[2]+b.h[3]+b.h[4]+b.h[5]+b.h[6]+b.h[7]): i32; }; @test fn arg_struct32_deref() void = { let v: t32; v.h[0]=1u32;v.h[1]=2u32;v.h[2]=3u32;v.h[3]=4u32; v.h[4]=5u32;v.h[5]=6u32;v.h[6]=7u32;v.h[7]=8u32; let p: *t32 = &v; assert(sum_arg_struct32_deref(*p) == 36i32); }; fn sum_arg_struct32_ident(b: t32) i32 = { return (b.h[0]+b.h[1]+b.h[2]+b.h[3]+b.h[4]+b.h[5]+b.h[6]+b.h[7]): i32; }; @test fn arg_struct32_ident() void = { let v: t32; v.h[0]=1u32;v.h[1]=2u32;v.h[2]=3u32;v.h[3]=4u32; v.h[4]=5u32;v.h[5]=6u32;v.h[6]=7u32;v.h[7]=8u32; assert(sum_arg_struct32_ident(v) == 36i32); };