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.
76 lines
2.4 KiB
Plaintext
76 lines
2.4 KiB
Plaintext
// oddstruct_byval_ret_test — by-value RETURN of a struct whose total size is an
|
|
// "odd" sub-8 width {3,5,6,7} (a single INTEGER eightbyte in RAX), migrated from
|
|
// test/wcc/949_oddstruct_byval_ret_run.c (#107). Pre-#107 cstage's N_LET receive
|
|
// fell past every arm for these sizes and SILENTLY DROPPED the CALL (exit 0,
|
|
// reading an uninit slot); wwstage's generic fallback emitted a single MOVQ, so
|
|
// it was both a silent miscompile AND a gate-blind cs≠ww divergence. The #107
|
|
// fix mirrors wwstage's single-MOVQ receive. Each @test reads back the planted
|
|
// fields as primitives (the whole eightbyte must reach the caller, not just AX's
|
|
// low byte); T2 keeps the cs==ww net. Sizes 8/12/24 lock the existing
|
|
// sized-tail / multi-word receive paths were not perturbed.
|
|
|
|
package oddstruct_byval_ret_test;
|
|
|
|
type T3 = struct { a: u8, b: u8, c: u8 };
|
|
type T5 = struct @packed { a: u8, b: u32 };
|
|
type T6 = struct { a: u16, b: u16, c: u16 };
|
|
type T7 = struct @packed { a: u8, b: u16, c: u32 };
|
|
type T8 = struct { a: i32, b: i32 };
|
|
type T12 = struct { a: i32, b: i32, c: i32 };
|
|
type T24 = struct { a: i64, b: i64, c: i64 };
|
|
|
|
fn mk3() T3 = { return T3 { a = 116u8, b = 22u8, c = 33u8 }; };
|
|
fn mk5() T5 = { return T5 { a = 9u8, b = 116u32 }; };
|
|
fn mk6() T6 = { return T6 { a = 9u16, b = 22u16, c = 116u16 }; };
|
|
fn mk7() T7 = { return T7 { a = 9u8, b = 22u16, c = 116u32 }; };
|
|
fn mk8() T8 = { return T8 { a = 116, b = 22 }; };
|
|
fn mk12() T12 = { return T12 { a = 9, b = 22, c = 116 }; };
|
|
fn mk24() T24 = { return T24 { a = 9i64, b = 22i64, c = 116i64 }; };
|
|
|
|
@test fn s3_u8x3_fieldA() void = {
|
|
let r: T3 = mk3();
|
|
assert(r.a: i32 == 116);
|
|
assert(r.b: i32 == 22);
|
|
assert(r.c: i32 == 33);
|
|
};
|
|
|
|
@test fn s5_packed_fieldB() void = {
|
|
let r: T5 = mk5();
|
|
assert(r.a: i32 == 9);
|
|
assert(r.b: i32 == 116);
|
|
};
|
|
|
|
@test fn s6_u16x3_fieldC() void = {
|
|
let r: T6 = mk6();
|
|
assert(r.a: i32 == 9);
|
|
assert(r.b: i32 == 22);
|
|
assert(r.c: i32 == 116);
|
|
};
|
|
|
|
@test fn s7_packed_fieldC() void = {
|
|
let r: T7 = mk7();
|
|
assert(r.a: i32 == 9);
|
|
assert(r.b: i32 == 22);
|
|
assert(r.c: i32 == 116);
|
|
};
|
|
|
|
@test fn s8_i32x2_fieldA() void = {
|
|
let r: T8 = mk8();
|
|
assert(r.a == 116);
|
|
assert(r.b == 22);
|
|
};
|
|
|
|
@test fn s12_i32x3_fieldC() void = {
|
|
let r: T12 = mk12();
|
|
assert(r.a == 9);
|
|
assert(r.b == 22);
|
|
assert(r.c == 116);
|
|
};
|
|
|
|
@test fn s24_i64x3_fieldC() void = {
|
|
let r: T24 = mk24();
|
|
assert(r.a == 9i64);
|
|
assert(r.b == 22i64);
|
|
assert(r.c == 116i64);
|
|
};
|