Continue fold-2: migrate the struct-by-value / sret round-trip family from bespoke build+run C twins to test/lang @test, retiring each twin in the same commit. Runtime coverage MOVES from $(TESTS) to test-lang (T1 runs+asserts via `ww test`) + test-lang-byteid (T2 keeps cs==ww .s byte-id); the $(TESTS) headline drops 6. Every assert is a primitive int/u8/bool comparison (no fmt/strconv in the assert path); each returned struct/tuple FIELD is asserted individually so a dropped/mis-offset/over-wide word FAILS. 46 @test cases, a strict superset of the 46 C rows (799=4, 925=10, 930=6, 949odd=7, 949chained=9, 949aggret=10). 799_tuple_sret_receive_run.c -> tuple_sret_receive_test.ww (#10 Fold B: over-4-GP tuple `([]u8,[]u8)` sret RECEIVE — destructure/single-var/return-forward/reassign; len() only on destructured bindings, never len(t.N)) 925_sret_struct_return_run.c -> sret_struct_return_test.ww (#23: >24B sret round-trip; 32B/40B/nested/slice-payload, reassign-receive, struct16-by-value-arg #11 collision, N_IDENT return rhs, forward #9 simple/multi-arg/slice) 930_sret_narrow_field_run.c -> sret_narrow_field_test.ww (#33: sret narrow trailing-field copy — bool/u8/i16/i32 + mixed bool+i32+i64 after the 24B slice) 949_oddstruct_byval_ret_run.c -> oddstruct_byval_ret_test.ww (#107: by-value return of odd sub-8 size {3,5,6,7} single-eightbyte + 8/12/24 boundaries) 949_chained_dot_struct_copy_run.c -> chained_dot_struct_copy_test.ww (#107 sibling: chained-DOT `t.m.l = s` natural-size tail copy {0..7} + via-CX global dest; neighbour z is the oracle) 949_aggret_source_run.c -> aggret_source_test.ww (#272: aggregate return from every addressable source — arrlit/N_DOT/N_INDEX/deref/ident + >24B sret arm + global-receive caller-half) This family is sret / struct-by-value-return (the #107/#38/#271/#272 ABI area): all 6 new files are byte-id cs==ww (no fold-5 divergence surfaced). Bump LANGBYTEID_EXPECTED_MIN 43->49 to ratchet the new corpus floor.
106 lines
3.1 KiB
Plaintext
106 lines
3.1 KiB
Plaintext
// aggret_source_test — aggregate return-by-value from every ADDRESSABLE source
|
|
// shape (#272), migrated from test/wcc/949_aggret_source_run.c. The N_RETURN
|
|
// aggregate arms gated the source on N_IDENT || N_STRUCTLIT; every OTHER
|
|
// aggregate rvalue (array literal, struct/array field N_DOT, array element
|
|
// N_INDEX, deref *p) fell to the scalar-AX default = a silent truncation to the
|
|
// first 8 bytes, and both stages emitted byte-IDENTICAL wrong asm (#263 pure
|
|
// form — byte-id alone could NOT catch it). Each @test asserts every returned
|
|
// member as a primitive (a dropped word fails); T2 keeps the cs==ww net. Also
|
|
// covers the #272 commit-2 caller-half: receive into a GLOBAL ≤24B / >24B array.
|
|
|
|
package aggret_source_test;
|
|
|
|
type box_da = struct { a: [3]i64 };
|
|
type pair_sd = struct { a: i64, b: i64 };
|
|
type box_sd = struct { p: pair_sd };
|
|
type pair_sr = struct { a: i64, b: i64 };
|
|
|
|
let g2_idx: [2][3]i64 = [[1i64,2i64,3i64],[4i64,5i64,6i64]];
|
|
let g_recv: [3]i64 = [0i64, 0i64, 0i64];
|
|
let g_recv4: [4]i64 = [0i64,0i64,0i64,0i64];
|
|
|
|
fn mk_arrlit() [3]i64 = { return [1i64, 2i64, 3i64]; };
|
|
fn mk_da() [3]i64 = { let o: box_da = box_da { a = [10i64, 20i64, 30i64] }; return o.a; };
|
|
fn mk_idx() [3]i64 = { return g2_idx[1]; };
|
|
fn mk_deref(p: *[3]i64) [3]i64 = { return *p; };
|
|
fn mk_ident() [3]i64 = { let a: [3]i64 = [2i64, 4i64, 6i64]; return a; };
|
|
fn mk_deref4(p: *[4]i64) [4]i64 = { return *p; };
|
|
fn mk_sd() pair_sd = { let bx: box_sd = box_sd { p = pair_sd { a = 3i64, b = 4i64 } }; return bx.p; };
|
|
fn mk_sr(p: *pair_sr) pair_sr = { return *p; };
|
|
fn mk_grecv() [3]i64 = { return [4i64, 5i64, 6i64]; };
|
|
fn mk_grecv4(p: *[4]i64) [4]i64 = { return *p; };
|
|
|
|
@test fn arrlit() void = {
|
|
let r: [3]i64 = mk_arrlit();
|
|
assert(r[0] == 1i64);
|
|
assert(r[1] == 2i64);
|
|
assert(r[2] == 3i64);
|
|
};
|
|
|
|
@test fn dot_arrfield() void = {
|
|
let r: [3]i64 = mk_da();
|
|
assert(r[0] == 10i64);
|
|
assert(r[1] == 20i64);
|
|
assert(r[2] == 30i64);
|
|
};
|
|
|
|
@test fn index_elem() void = {
|
|
let r: [3]i64 = mk_idx();
|
|
assert(r[0] == 4i64);
|
|
assert(r[1] == 5i64);
|
|
assert(r[2] == 6i64);
|
|
};
|
|
|
|
@test fn deref() void = {
|
|
let a: [3]i64 = [7i64, 8i64, 9i64];
|
|
let r: [3]i64 = mk_deref(&a);
|
|
assert(r[0] == 7i64);
|
|
assert(r[1] == 8i64);
|
|
assert(r[2] == 9i64);
|
|
};
|
|
|
|
@test fn ident_ctl() void = {
|
|
let r: [3]i64 = mk_ident();
|
|
assert(r[0] == 2i64);
|
|
assert(r[1] == 4i64);
|
|
assert(r[2] == 6i64);
|
|
};
|
|
|
|
@test fn deref_sret() void = {
|
|
let a: [4]i64 = [1i64, 2i64, 3i64, 4i64];
|
|
let r: [4]i64 = mk_deref4(&a);
|
|
assert(r[0] == 1i64);
|
|
assert(r[1] == 2i64);
|
|
assert(r[2] == 3i64);
|
|
assert(r[3] == 4i64);
|
|
};
|
|
|
|
@test fn struct_dot() void = {
|
|
let r: pair_sd = mk_sd();
|
|
assert(r.a == 3i64);
|
|
assert(r.b == 4i64);
|
|
};
|
|
|
|
@test fn struct_deref() void = {
|
|
let x: pair_sr = pair_sr { a = 5i64, b = 9i64 };
|
|
let r: pair_sr = mk_sr(&x);
|
|
assert(r.a == 5i64);
|
|
assert(r.b == 9i64);
|
|
};
|
|
|
|
@test fn global_recv() void = {
|
|
g_recv = mk_grecv();
|
|
assert(g_recv[0] == 4i64);
|
|
assert(g_recv[1] == 5i64);
|
|
assert(g_recv[2] == 6i64);
|
|
};
|
|
|
|
@test fn global_recv_sret() void = {
|
|
let a: [4]i64 = [4i64, 5i64, 6i64, 7i64];
|
|
g_recv4 = mk_grecv4(&a);
|
|
assert(g_recv4[0] == 4i64);
|
|
assert(g_recv4[1] == 5i64);
|
|
assert(g_recv4[2] == 6i64);
|
|
assert(g_recv4[3] == 7i64);
|
|
};
|