commit c0e90312fcb8a7919cd5be992acbfc00a6810931 (tree)
parent 97ef8f1f8e693733e4f208a01b298dfb334fa719
Author: Jacob Young <jacobly0@users.noreply.github.com>
Date: Tue, 21 Apr 2026 22:38:25 -0400
test: c abi regression tests for aarch64 failures
Diffstat:
3 files changed, 246 insertions(+), 17 deletions(-)
diff --git a/test/c_abi/cfuncs.c b/test/c_abi/cfuncs.c
@@ -24,11 +24,6 @@ static void assert_or_panic(bool ok) {
# endif
#endif
-#if defined(__aarch64__) && defined(__linux__)
-// TODO: https://github.com/ziglang/zig/issues/14908
-#define ZIG_BUG_14908
-#endif
-
#ifdef __i386__
# define ZIG_NO_I128
#endif
@@ -205,6 +200,74 @@ double complex zig_cmultd_comp(double a_r, double a_i, double b_r, double b_i);
float complex zig_cmultf(float complex a, float complex b);
double complex zig_cmultd(double complex a, double complex b);
+struct Struct_u8 {
+ uint8_t a;
+};
+
+struct Struct_u8 zig_ret_struct_u8(void);
+
+void zig_struct_u8(struct Struct_u8, size_t);
+
+struct Struct_u8 c_ret_struct_u8(void) {
+ return (struct Struct_u8){ 4 };
+}
+
+void c_struct_u8(struct Struct_u8 s, size_t i) {
+ assert_or_panic(s.a == 5);
+ assert_or_panic(i == 6);
+}
+
+struct Struct_u16 {
+ uint16_t a;
+};
+
+struct Struct_u16 zig_ret_struct_u16(void);
+
+void zig_struct_u16(struct Struct_u16, size_t);
+
+struct Struct_u16 c_ret_struct_u16(void) {
+ return (struct Struct_u16){ 10 };
+}
+
+void c_struct_u16(struct Struct_u16 s, size_t i) {
+ assert_or_panic(s.a == 11);
+ assert_or_panic(i == 12);
+}
+
+struct Struct_u32 {
+ uint32_t a;
+};
+
+struct Struct_u32 zig_ret_struct_u32(void);
+
+void zig_struct_u32(struct Struct_u32, size_t);
+
+struct Struct_u32 c_ret_struct_u32(void) {
+ return (struct Struct_u32){ 16 };
+}
+
+void c_struct_u32(struct Struct_u32 s, size_t i) {
+ assert_or_panic(s.a == 17);
+ assert_or_panic(i == 18);
+}
+
+struct Struct_u64 {
+ uint64_t a;
+};
+
+struct Struct_u64 zig_ret_struct_u64(void);
+
+void zig_struct_u64(struct Struct_u64, size_t);
+
+struct Struct_u64 c_ret_struct_u64(void) {
+ return (struct Struct_u64){ 22 };
+}
+
+void c_struct_u64(struct Struct_u64 s, size_t i) {
+ assert_or_panic(s.a == 23);
+ assert_or_panic(i == 24);
+}
+
struct Struct_u64_u64 {
uint64_t a;
uint64_t b;
@@ -2677,10 +2740,8 @@ void run_c_tests(void) {
}
#endif
-#ifndef ZIG_BUG_14908
zig_i8(-1);
zig_i16(-2);
-#endif
zig_i32(-3);
zig_i64(-4);
@@ -2741,6 +2802,60 @@ void run_c_tests(void) {
}
#endif
+#if !defined(__AARCH_BIG_ENDIAN)
+#if !defined(__mips64)
+#if !defined(ZIG_PPC32)
+#if !defined(__s390x__)
+ {
+ struct Struct_u8 s = zig_ret_struct_u8();
+ assert_or_panic(s.a == 1);
+ zig_struct_u8((struct Struct_u8){ .a = 2 }, 3);
+ }
+#endif
+#endif
+#endif
+#endif
+
+#if !defined(__AARCH_BIG_ENDIAN)
+#if !defined(__mips64)
+#if !defined(ZIG_PPC32)
+#if !defined(__s390x__)
+ {
+ struct Struct_u16 s = zig_ret_struct_u16();
+ assert_or_panic(s.a == 7);
+ zig_struct_u16((struct Struct_u16){ .a = 8 }, 9);
+ }
+#endif
+#endif
+#endif
+#endif
+
+#if !defined(__AARCH_BIG_ENDIAN)
+#if !defined(__mips64)
+#if !defined(ZIG_PPC32)
+#if !defined(__s390x__)
+ {
+ struct Struct_u32 s = zig_ret_struct_u32();
+ assert_or_panic(s.a == 13);
+ zig_struct_u32((struct Struct_u32){ .a = 14 }, 15);
+ }
+#endif
+#endif
+#endif
+#endif
+
+#if !defined(ZIG_PPC32)
+#if !defined(ZIG_RISCV32)
+#if !defined(__s390x__)
+ {
+ struct Struct_u64 s = zig_ret_struct_u64();
+ assert_or_panic(s.a == 19);
+ zig_struct_u64((struct Struct_u64){ .a = 20 }, 21);
+ }
+#endif
+#endif
+#endif
+
#if !defined(ZIG_PPC32) && !defined(__hexagon__) && !defined(__s390x__)
{
struct Struct_u64_u64 s = zig_ret_struct_u64_u64();
@@ -2818,7 +2933,7 @@ void run_c_tests(void) {
#endif
#endif
-#if !defined __i386__ && !defined __arm__ && !defined __aarch64__ && \
+#if !defined __i386__ && !defined __arm__ && !defined(__AARCH_BIG_ENDIAN) && \
!defined __powerpc__ && !defined ZIG_RISCV64 && !defined(__loongarch__) && \
!defined(__mips64__) && !defined(__hexagon__) && !defined(__s390x__)
{
@@ -2827,7 +2942,7 @@ void run_c_tests(void) {
}
#endif
-#if !defined __arm__ && !defined __aarch64__ && \
+#if !defined __arm__ && !defined(__AARCH_BIG_ENDIAN) && \
!defined __powerpc__ && !defined ZIG_RISCV64 && !defined(__loongarch__) && \
!defined(__mips64__) && !defined(__hexagon__) && !defined(__s390x__)
{
diff --git a/test/c_abi/main.zig b/test/c_abi/main.zig
@@ -269,6 +269,117 @@ export fn zig_cmultd_comp(a_r: f64, a_i: f64, b_r: f64, b_i: f64) ComplexDouble
return .{ .real = 1.5, .imag = 13.5 };
}
+const Struct_u8 = extern struct {
+ a: u8,
+};
+
+export fn zig_ret_struct_u8() Struct_u8 {
+ return .{ .a = 1 };
+}
+
+export fn zig_struct_u8(s: Struct_u8, i: usize) void {
+ expect(s.a == 2) catch @panic("test failure");
+ expect(i == 3) catch @panic("test failure");
+}
+
+extern fn c_ret_struct_u8() Struct_u8;
+
+extern fn c_struct_u8(Struct_u8, usize) void;
+
+test "C ABI struct u8" {
+ if (builtin.cpu.arch == .aarch64_be) return error.SkipZigTest;
+ if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
+ if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
+ if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
+
+ const s = c_ret_struct_u8();
+ try expect(s.a == 4);
+ c_struct_u8(.{ .a = 5 }, 6);
+}
+
+const Struct_u16 = extern struct {
+ a: u16,
+};
+
+export fn zig_ret_struct_u16() Struct_u16 {
+ return .{ .a = 7 };
+}
+
+export fn zig_struct_u16(s: Struct_u16, i: usize) void {
+ expect(s.a == 8) catch @panic("test failure");
+ expect(i == 9) catch @panic("test failure");
+}
+
+extern fn c_ret_struct_u16() Struct_u16;
+
+extern fn c_struct_u16(Struct_u16, usize) void;
+
+test "C ABI struct u16" {
+ if (builtin.cpu.arch == .aarch64_be) return error.SkipZigTest;
+ if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
+ if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
+ if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
+
+ const s = c_ret_struct_u16();
+ try expect(s.a == 10);
+ c_struct_u16(.{ .a = 11 }, 12);
+}
+
+const Struct_u32 = extern struct {
+ a: u32,
+};
+
+export fn zig_ret_struct_u32() Struct_u32 {
+ return .{ .a = 13 };
+}
+
+export fn zig_struct_u32(s: Struct_u32, i: usize) void {
+ expect(s.a == 14) catch @panic("test failure");
+ expect(i == 15) catch @panic("test failure");
+}
+
+extern fn c_ret_struct_u32() Struct_u32;
+
+extern fn c_struct_u32(Struct_u32, usize) void;
+
+test "C ABI struct u32" {
+ if (builtin.cpu.arch == .aarch64_be) return error.SkipZigTest;
+ if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
+ if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
+ if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
+
+ const s = c_ret_struct_u32();
+ try expect(s.a == 16);
+ c_struct_u32(.{ .a = 17 }, 18);
+}
+
+const Struct_u64 = extern struct {
+ a: u64,
+};
+
+export fn zig_ret_struct_u64() Struct_u64 {
+ return .{ .a = 19 };
+}
+
+export fn zig_struct_u64(s: Struct_u64, i: usize) void {
+ expect(s.a == 20) catch @panic("test failure");
+ expect(i == 21) catch @panic("test failure");
+}
+
+extern fn c_ret_struct_u64() Struct_u64;
+
+extern fn c_struct_u64(Struct_u64, usize) void;
+
+test "C ABI struct u64" {
+ if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
+ if (builtin.cpu.arch == .riscv32) return error.SkipZigTest;
+ if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
+
+ const s = c_ret_struct_u64();
+ try expect(s.a == 22);
+ c_struct_u64(.{ .a = 23 }, 24);
+}
+
const Struct_u64_u64 = extern struct {
a: u64,
b: u64,
@@ -5596,7 +5707,6 @@ test "CFF: Zig returns to C" {
test "CFF: C passes to Zig" {
if (builtin.target.cpu.arch == .x86) return error.SkipZigTest;
if (builtin.cpu.arch.isRISCV() and builtin.mode != .Debug) return error.SkipZigTest;
- if (builtin.cpu.arch == .aarch64 and builtin.mode != .Debug) return error.SkipZigTest;
if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
@@ -5606,7 +5716,6 @@ test "CFF: C passes to Zig" {
try expectOk(c_send_CFF());
}
test "CFF: C returns to Zig" {
- if (builtin.cpu.arch == .aarch64 and builtin.mode != .Debug) return error.SkipZigTest;
if (builtin.cpu.arch.isRISCV() and builtin.mode != .Debug) return error.SkipZigTest;
if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
@@ -5738,7 +5847,17 @@ test "C function that takes byval struct called via function pointer" {
extern fn c_f16(f16) f16;
test "f16 bare" {
- if (!builtin.cpu.arch.isAARCH64()) return error.SkipZigTest;
+ if (builtin.cpu.arch == .x86_64) return error.SkipZigTest;
+ if (builtin.cpu.arch == .x86) return error.SkipZigTest;
+ if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
+ if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
+ if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
+ if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest;
+ if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
+ if (builtin.cpu.arch.isWasm()) return error.SkipZigTest;
+ if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
+
+ if (builtin.cpu.arch.isArm()) return error.SkipZigTest;
const a = c_f16(12);
try expect(a == 34);
diff --git a/test/tests.zig b/test/tests.zig
@@ -2795,11 +2795,6 @@ pub fn addCAbiTests(b: *std.Build, options: CAbiTestOptions) *Step {
} else continue;
}
- if (target.os.tag == .windows and target.cpu.arch == .aarch64) {
- // https://github.com/ziglang/zig/issues/14908
- continue;
- }
-
const test_mod = b.createModule(.{
.root_source_file = b.path("test/c_abi/main.zig"),
.target = resolved_target,