| author | |
| committer | |
| log | 0bebd6108e586c5b6e216b4e69c1a06aa07d411d |
| tree | 3d0cb452e54fc5801219aed738be9b776e4053e9 |
| parent | 6f7607c8e23fd8fd5d8fdbc28b119590f092dd0b |
| signature |
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 { | ... | @@ -102,6 +102,13 @@ pub fn classifyTypeForLlvm(ty: Type, zcu: *const Zcu) LlvmClass { |
| 102 | assert(layout.tag_size == 0); | 102 | assert(layout.tag_size == 0); |
| 103 | if (union_obj.field_types.len > 1) return .indirect; | 103 | if (union_obj.field_types.len > 1) return .indirect; |
| 104 | const first_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[0]); | 104 | 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 | } | ||
| 105 | return classifyTypeForLlvm(first_field_ty, zcu); | 112 | return classifyTypeForLlvm(first_field_ty, zcu); |
| 106 | }, | 113 | }, |
| 107 | .error_union, | 114 | .error_union, |
test/c_abi/cfuncs.c+20| ... | @@ -15749,6 +15749,26 @@ void c_test_struct_array_5_f64(void) { | ... | @@ -15749,6 +15749,26 @@ void c_test_struct_array_5_f64(void) { |
| 15749 | zig_struct_array_5_f64((struct Struct_array_5_f64){ .a = { 6, 7, 8, 9, 10 } }, 11); | 15749 | zig_struct_array_5_f64((struct Struct_array_5_f64){ .a = { 6, 7, 8, 9, 10 } }, 11); |
| 15750 | } | 15750 | } |
| 15751 | 15751 | ||
| 15752 | union Union_f64 { | ||
| 15753 | double a; | ||
| 15754 | }; | ||
| 15755 | |||
| 15756 | union Union_f64 zig_ret_union_f64(void); | ||
| 15757 | void zig_union_f64(union Union_f64, size_t); | ||
| 15758 | |||
| 15759 | union Union_f64 c_ret_union_f64(void) { | ||
| 15760 | return (union Union_f64){ .a = 4 }; | ||
| 15761 | } | ||
| 15762 | void c_union_f64(union Union_f64 s, size_t i) { | ||
| 15763 | assert_or_panic(s.a == 5); | ||
| 15764 | assert_or_panic(i == 6); | ||
| 15765 | } | ||
| 15766 | void 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 | |||
| 15752 | struct Struct_u32_Union_u32_u32u32 { | 15772 | struct Struct_u32_Union_u32_u32u32 { |
| 15753 | uint32_t a; | 15773 | uint32_t a; |
| 15754 | union { | 15774 | union { |
test/c_abi/main.zig+30| ... | @@ -16918,6 +16918,36 @@ test "struct [5]f64" { | ... | @@ -16918,6 +16918,36 @@ test "struct [5]f64" { |
| 16918 | c_test_struct_array_5_f64(); | 16918 | c_test_struct_array_5_f64(); |
| 16919 | } | 16919 | } |
| 16920 | 16920 | ||
| 16921 | const Union_f64 = extern union { | ||
| 16922 | a: f64, | ||
| 16923 | }; | ||
| 16924 | |||
| 16925 | export fn zig_ret_union_f64() Union_f64 { | ||
| 16926 | return .{ .a = 1 }; | ||
| 16927 | } | ||
| 16928 | export 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 | |||
| 16933 | extern fn c_ret_union_f64() Union_f64; | ||
| 16934 | extern fn c_union_f64(Union_f64, usize) void; | ||
| 16935 | extern fn c_test_union_f64() void; | ||
| 16936 | |||
| 16937 | test "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 | |||
| 16921 | const Struct_u32_Union_u32_u32u32 = extern struct { | 16951 | const Struct_u32_Union_u32_u32u32 = extern struct { |
| 16922 | a: u32, | 16952 | a: u32, |
| 16923 | b: extern union { | 16953 | b: extern union { |