authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-04-21 22:38:25-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-04-22 14:35:22+02:00
logc0e90312fcb8a7919cd5be992acbfc00a6810931
tree6c850ad74a30ba539d3067f1043afa1312af7383
parent97ef8f1f8e693733e4f208a01b298dfb334fa719

test: c abi regression tests for aarch64 failures


3 files changed, 246 insertions(+), 17 deletions(-)

test/c_abi/cfuncs.c+124-9
......@@ -24,11 +24,6 @@ static void assert_or_panic(bool ok) {
2424# endif
2525#endif
2626
27#if defined(__aarch64__) && defined(__linux__)
28// TODO: https://github.com/ziglang/zig/issues/14908
29#define ZIG_BUG_14908
30#endif
31
3227#ifdef __i386__
3328# define ZIG_NO_I128
3429#endif
......@@ -205,6 +200,74 @@ double complex zig_cmultd_comp(double a_r, double a_i, double b_r, double b_i);
205200float complex zig_cmultf(float complex a, float complex b);
206201double complex zig_cmultd(double complex a, double complex b);
207202
203struct Struct_u8 {
204 uint8_t a;
205};
206
207struct Struct_u8 zig_ret_struct_u8(void);
208
209void zig_struct_u8(struct Struct_u8, size_t);
210
211struct Struct_u8 c_ret_struct_u8(void) {
212 return (struct Struct_u8){ 4 };
213}
214
215void c_struct_u8(struct Struct_u8 s, size_t i) {
216 assert_or_panic(s.a == 5);
217 assert_or_panic(i == 6);
218}
219
220struct Struct_u16 {
221 uint16_t a;
222};
223
224struct Struct_u16 zig_ret_struct_u16(void);
225
226void zig_struct_u16(struct Struct_u16, size_t);
227
228struct Struct_u16 c_ret_struct_u16(void) {
229 return (struct Struct_u16){ 10 };
230}
231
232void c_struct_u16(struct Struct_u16 s, size_t i) {
233 assert_or_panic(s.a == 11);
234 assert_or_panic(i == 12);
235}
236
237struct Struct_u32 {
238 uint32_t a;
239};
240
241struct Struct_u32 zig_ret_struct_u32(void);
242
243void zig_struct_u32(struct Struct_u32, size_t);
244
245struct Struct_u32 c_ret_struct_u32(void) {
246 return (struct Struct_u32){ 16 };
247}
248
249void c_struct_u32(struct Struct_u32 s, size_t i) {
250 assert_or_panic(s.a == 17);
251 assert_or_panic(i == 18);
252}
253
254struct Struct_u64 {
255 uint64_t a;
256};
257
258struct Struct_u64 zig_ret_struct_u64(void);
259
260void zig_struct_u64(struct Struct_u64, size_t);
261
262struct Struct_u64 c_ret_struct_u64(void) {
263 return (struct Struct_u64){ 22 };
264}
265
266void c_struct_u64(struct Struct_u64 s, size_t i) {
267 assert_or_panic(s.a == 23);
268 assert_or_panic(i == 24);
269}
270
208271struct Struct_u64_u64 {
209272 uint64_t a;
210273 uint64_t b;
......@@ -2677,10 +2740,8 @@ void run_c_tests(void) {
26772740 }
26782741#endif
26792742
2680#ifndef ZIG_BUG_14908
26812743 zig_i8(-1);
26822744 zig_i16(-2);
2683#endif
26842745 zig_i32(-3);
26852746 zig_i64(-4);
26862747
......@@ -2741,6 +2802,60 @@ void run_c_tests(void) {
27412802 }
27422803#endif
27432804
2805#if !defined(__AARCH_BIG_ENDIAN)
2806#if !defined(__mips64)
2807#if !defined(ZIG_PPC32)
2808#if !defined(__s390x__)
2809 {
2810 struct Struct_u8 s = zig_ret_struct_u8();
2811 assert_or_panic(s.a == 1);
2812 zig_struct_u8((struct Struct_u8){ .a = 2 }, 3);
2813 }
2814#endif
2815#endif
2816#endif
2817#endif
2818
2819#if !defined(__AARCH_BIG_ENDIAN)
2820#if !defined(__mips64)
2821#if !defined(ZIG_PPC32)
2822#if !defined(__s390x__)
2823 {
2824 struct Struct_u16 s = zig_ret_struct_u16();
2825 assert_or_panic(s.a == 7);
2826 zig_struct_u16((struct Struct_u16){ .a = 8 }, 9);
2827 }
2828#endif
2829#endif
2830#endif
2831#endif
2832
2833#if !defined(__AARCH_BIG_ENDIAN)
2834#if !defined(__mips64)
2835#if !defined(ZIG_PPC32)
2836#if !defined(__s390x__)
2837 {
2838 struct Struct_u32 s = zig_ret_struct_u32();
2839 assert_or_panic(s.a == 13);
2840 zig_struct_u32((struct Struct_u32){ .a = 14 }, 15);
2841 }
2842#endif
2843#endif
2844#endif
2845#endif
2846
2847#if !defined(ZIG_PPC32)
2848#if !defined(ZIG_RISCV32)
2849#if !defined(__s390x__)
2850 {
2851 struct Struct_u64 s = zig_ret_struct_u64();
2852 assert_or_panic(s.a == 19);
2853 zig_struct_u64((struct Struct_u64){ .a = 20 }, 21);
2854 }
2855#endif
2856#endif
2857#endif
2858
27442859#if !defined(ZIG_PPC32) && !defined(__hexagon__) && !defined(__s390x__)
27452860 {
27462861 struct Struct_u64_u64 s = zig_ret_struct_u64_u64();
......@@ -2818,7 +2933,7 @@ void run_c_tests(void) {
28182933#endif
28192934#endif
28202935
2821#if !defined __i386__ && !defined __arm__ && !defined __aarch64__ && \
2936#if !defined __i386__ && !defined __arm__ && !defined(__AARCH_BIG_ENDIAN) && \
28222937 !defined __powerpc__ && !defined ZIG_RISCV64 && !defined(__loongarch__) && \
28232938 !defined(__mips64__) && !defined(__hexagon__) && !defined(__s390x__)
28242939 {
......@@ -2827,7 +2942,7 @@ void run_c_tests(void) {
28272942 }
28282943#endif
28292944
2830#if !defined __arm__ && !defined __aarch64__ && \
2945#if !defined __arm__ && !defined(__AARCH_BIG_ENDIAN) && \
28312946 !defined __powerpc__ && !defined ZIG_RISCV64 && !defined(__loongarch__) && \
28322947 !defined(__mips64__) && !defined(__hexagon__) && !defined(__s390x__)
28332948 {
test/c_abi/main.zig+122-3
......@@ -269,6 +269,117 @@ export fn zig_cmultd_comp(a_r: f64, a_i: f64, b_r: f64, b_i: f64) ComplexDouble
269269 return .{ .real = 1.5, .imag = 13.5 };
270270}
271271
272const Struct_u8 = extern struct {
273 a: u8,
274};
275
276export fn zig_ret_struct_u8() Struct_u8 {
277 return .{ .a = 1 };
278}
279
280export fn zig_struct_u8(s: Struct_u8, i: usize) void {
281 expect(s.a == 2) catch @panic("test failure");
282 expect(i == 3) catch @panic("test failure");
283}
284
285extern fn c_ret_struct_u8() Struct_u8;
286
287extern fn c_struct_u8(Struct_u8, usize) void;
288
289test "C ABI struct u8" {
290 if (builtin.cpu.arch == .aarch64_be) return error.SkipZigTest;
291 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
292 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
293 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
294
295 const s = c_ret_struct_u8();
296 try expect(s.a == 4);
297 c_struct_u8(.{ .a = 5 }, 6);
298}
299
300const Struct_u16 = extern struct {
301 a: u16,
302};
303
304export fn zig_ret_struct_u16() Struct_u16 {
305 return .{ .a = 7 };
306}
307
308export fn zig_struct_u16(s: Struct_u16, i: usize) void {
309 expect(s.a == 8) catch @panic("test failure");
310 expect(i == 9) catch @panic("test failure");
311}
312
313extern fn c_ret_struct_u16() Struct_u16;
314
315extern fn c_struct_u16(Struct_u16, usize) void;
316
317test "C ABI struct u16" {
318 if (builtin.cpu.arch == .aarch64_be) return error.SkipZigTest;
319 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
320 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
321 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
322
323 const s = c_ret_struct_u16();
324 try expect(s.a == 10);
325 c_struct_u16(.{ .a = 11 }, 12);
326}
327
328const Struct_u32 = extern struct {
329 a: u32,
330};
331
332export fn zig_ret_struct_u32() Struct_u32 {
333 return .{ .a = 13 };
334}
335
336export fn zig_struct_u32(s: Struct_u32, i: usize) void {
337 expect(s.a == 14) catch @panic("test failure");
338 expect(i == 15) catch @panic("test failure");
339}
340
341extern fn c_ret_struct_u32() Struct_u32;
342
343extern fn c_struct_u32(Struct_u32, usize) void;
344
345test "C ABI struct u32" {
346 if (builtin.cpu.arch == .aarch64_be) return error.SkipZigTest;
347 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
348 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
349 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
350
351 const s = c_ret_struct_u32();
352 try expect(s.a == 16);
353 c_struct_u32(.{ .a = 17 }, 18);
354}
355
356const Struct_u64 = extern struct {
357 a: u64,
358};
359
360export fn zig_ret_struct_u64() Struct_u64 {
361 return .{ .a = 19 };
362}
363
364export fn zig_struct_u64(s: Struct_u64, i: usize) void {
365 expect(s.a == 20) catch @panic("test failure");
366 expect(i == 21) catch @panic("test failure");
367}
368
369extern fn c_ret_struct_u64() Struct_u64;
370
371extern fn c_struct_u64(Struct_u64, usize) void;
372
373test "C ABI struct u64" {
374 if (builtin.cpu.arch.isPowerPC32()) return error.SkipZigTest;
375 if (builtin.cpu.arch == .riscv32) return error.SkipZigTest;
376 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
377
378 const s = c_ret_struct_u64();
379 try expect(s.a == 22);
380 c_struct_u64(.{ .a = 23 }, 24);
381}
382
272383const Struct_u64_u64 = extern struct {
273384 a: u64,
274385 b: u64,
......@@ -5596,7 +5707,6 @@ test "CFF: Zig returns to C" {
55965707test "CFF: C passes to Zig" {
55975708 if (builtin.target.cpu.arch == .x86) return error.SkipZigTest;
55985709 if (builtin.cpu.arch.isRISCV() and builtin.mode != .Debug) return error.SkipZigTest;
5599 if (builtin.cpu.arch == .aarch64 and builtin.mode != .Debug) return error.SkipZigTest;
56005710 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
56015711 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
56025712 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
......@@ -5606,7 +5716,6 @@ test "CFF: C passes to Zig" {
56065716 try expectOk(c_send_CFF());
56075717}
56085718test "CFF: C returns to Zig" {
5609 if (builtin.cpu.arch == .aarch64 and builtin.mode != .Debug) return error.SkipZigTest;
56105719 if (builtin.cpu.arch.isRISCV() and builtin.mode != .Debug) return error.SkipZigTest;
56115720 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
56125721 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
......@@ -5738,7 +5847,17 @@ test "C function that takes byval struct called via function pointer" {
57385847
57395848extern fn c_f16(f16) f16;
57405849test "f16 bare" {
5741 if (!builtin.cpu.arch.isAARCH64()) return error.SkipZigTest;
5850 if (builtin.cpu.arch == .x86_64) return error.SkipZigTest;
5851 if (builtin.cpu.arch == .x86) return error.SkipZigTest;
5852 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
5853 if (builtin.cpu.arch.isLoongArch()) return error.SkipZigTest;
5854 if (builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
5855 if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest;
5856 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
5857 if (builtin.cpu.arch.isWasm()) return error.SkipZigTest;
5858 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
5859
5860 if (builtin.cpu.arch.isArm()) return error.SkipZigTest;
57425861
57435862 const a = c_f16(12);
57445863 try expect(a == 34);
test/tests.zig-5
......@@ -2795,11 +2795,6 @@ pub fn addCAbiTests(b: *std.Build, options: CAbiTestOptions) *Step {
27952795 } else continue;
27962796 }
27972797
2798 if (target.os.tag == .windows and target.cpu.arch == .aarch64) {
2799 // https://github.com/ziglang/zig/issues/14908
2800 continue;
2801 }
2802
28032798 const test_mod = b.createModule(.{
28042799 .root_source_file = b.path("test/c_abi/main.zig"),
28052800 .target = resolved_target,