authorgravatar for techatrix@mailbox.orgTechatrix <techatrix@mailbox.org> 2026-08-04 01:08:16+02:00
committergravatar for techatrix@mailbox.orgTechatrix <techatrix@mailbox.org> 2026-08-05 15:27:02+02:00
log0bebd6108e586c5b6e216b4e69c1a06aa07d411d
tree3d0cb452e54fc5801219aed738be9b776e4053e9
parent6f7607c8e23fd8fd5d8fdbc28b119590f092dd0b
signaturebadge-check Signed by SSH key SHA256:HYC3SjXQcAt6uwv9pu/6OoVQ2rUH8rb5zKiUHSe9uxk

c_abi: fix union with single scalar array element on wasm


3 files changed, 57 insertions(+), 0 deletions(-)

src/codegen/wasm/abi.zig+7
......@@ -102,6 +102,13 @@ pub fn classifyTypeForLlvm(ty: Type, zcu: *const Zcu) LlvmClass {
102102 assert(layout.tag_size == 0);
103103 if (union_obj.field_types.len > 1) return .indirect;
104104 const first_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[0]);
105 if (first_field_ty.zigTypeTag(zcu) == .array) {
106 switch (first_field_ty.arrayLenIncludingSentinel(zcu)) {
107 0 => unreachable,
108 1 => return classifyTypeForLlvm(first_field_ty.childType(zcu), zcu),
109 else => {},
110 }
111 }
105112 return classifyTypeForLlvm(first_field_ty, zcu);
106113 },
107114 .error_union,
test/c_abi/cfuncs.c+20
......@@ -15749,6 +15749,26 @@ void c_test_struct_array_5_f64(void) {
1574915749 zig_struct_array_5_f64((struct Struct_array_5_f64){ .a = { 6, 7, 8, 9, 10 } }, 11);
1575015750}
1575115751
15752union Union_f64 {
15753 double a;
15754};
15755
15756union Union_f64 zig_ret_union_f64(void);
15757void zig_union_f64(union Union_f64, size_t);
15758
15759union Union_f64 c_ret_union_f64(void) {
15760 return (union Union_f64){ .a = 4 };
15761}
15762void c_union_f64(union Union_f64 s, size_t i) {
15763 assert_or_panic(s.a == 5);
15764 assert_or_panic(i == 6);
15765}
15766void c_test_union_f64(void) {
15767 union Union_f64 s = zig_ret_union_f64();
15768 assert_or_panic(s.a == 1);
15769 zig_union_f64((union Union_f64){ .a = 2 }, 3);
15770}
15771
1575215772struct Struct_u32_Union_u32_u32u32 {
1575315773 uint32_t a;
1575415774 union {
test/c_abi/main.zig+30
......@@ -16918,6 +16918,36 @@ test "struct [5]f64" {
1691816918 c_test_struct_array_5_f64();
1691916919}
1692016920
16921const Union_f64 = extern union {
16922 a: f64,
16923};
16924
16925export fn zig_ret_union_f64() Union_f64 {
16926 return .{ .a = 1 };
16927}
16928export fn zig_union_f64(s: Union_f64, i: usize) void {
16929 expect(s.a == 2) catch @panic("test failure");
16930 expect(i == 3) catch @panic("test failure");
16931}
16932
16933extern fn c_ret_union_f64() Union_f64;
16934extern fn c_union_f64(Union_f64, usize) void;
16935extern fn c_test_union_f64() void;
16936
16937test "union f64" {
16938 if (builtin.cpu.arch.isArm() and builtin.abi.float() == .soft) return error.SkipZigTest;
16939 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
16940 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16941 if (builtin.cpu.arch.isRiscv32()) return error.SkipZigTest;
16942 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
16943 if (builtin.cpu.arch == .x86 and builtin.os.tag == .windows) return error.SkipZigTest;
16944
16945 const s = c_ret_union_f64();
16946 try expect(s.a == 4);
16947 c_union_f64(.{ .a = 5 }, 6);
16948 c_test_union_f64();
16949}
16950
1692116951const Struct_u32_Union_u32_u32u32 = extern struct {
1692216952 a: u32,
1692316953 b: extern union {