authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-07-17 06:01:26-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-07-27 14:44:41-04:00
logba23bad8380f023455fed65e1631089f17e0535d
treebf0b1ab0d182f1644b159ed0b4e34c1a946353b1
parentf2f770fdd3818d1ec14e51ce752aca5beb08e150

x86_64: implement c abi for array fields

Closes #36195

3 files changed, 621 insertions(+), 10 deletions(-)

src/codegen/x86_64/abi.zig+31-10
......@@ -358,11 +358,10 @@ fn classifySystemVStruct(
358358 while (field_it.next()) |field_index| {
359359 const field_ty = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);
360360 const field_align = loaded_struct.field_aligns.getOrNone(ip, field_index);
361 byte_offset = std.mem.alignForward(
362 u64,
363 byte_offset,
364 field_align.toByteUnits() orelse field_ty.abiAlignment(zcu).toByteUnits().?,
365 );
361 byte_offset = switch (field_align) {
362 .none => field_ty.abiAlignment(zcu),
363 else => field_align,
364 }.forward(byte_offset);
366365 if (zcu.typeToStruct(field_ty)) |field_loaded_struct| {
367366 switch (field_loaded_struct.layout) {
368367 .auto => unreachable,
......@@ -381,6 +380,9 @@ fn classifySystemVStruct(
381380 },
382381 .@"packed" => {},
383382 }
383 } else if (field_ty.zigTypeTag(zcu) == .array) {
384 byte_offset = classifySystemVArray(result, byte_offset, field_ty, zcu, target);
385 continue;
384386 }
385387 const field_classes = std.mem.sliceTo(&classifySystemV(field_ty, zcu, target, .other), .none);
386388 for (result[@intCast(byte_offset / 8)..][0..field_classes.len], field_classes) |*result_class, field_class|
......@@ -388,11 +390,7 @@ fn classifySystemVStruct(
388390 byte_offset += field_ty.abiSize(zcu);
389391 }
390392 const final_byte_offset = starting_byte_offset + loaded_struct.size;
391 std.debug.assert(final_byte_offset == std.mem.alignForward(
392 u64,
393 byte_offset,
394 loaded_struct.alignment.toByteUnits().?,
395 ));
393 std.debug.assert(final_byte_offset == loaded_struct.alignment.forward(byte_offset));
396394 return final_byte_offset;
397395}
398396
......@@ -424,6 +422,9 @@ fn classifySystemVUnion(
424422 },
425423 .@"packed" => {},
426424 }
425 } else if (field_ty.zigTypeTag(zcu) == .array) {
426 _ = classifySystemVArray(result, starting_byte_offset, field_ty, zcu, target);
427 continue;
427428 }
428429 const field_classes = std.mem.sliceTo(&classifySystemV(field_ty, zcu, target, .other), .none);
429430 for (result[@intCast(starting_byte_offset / 8)..][0..field_classes.len], field_classes) |*result_class, field_class|
......@@ -432,6 +433,26 @@ fn classifySystemVUnion(
432433 return starting_byte_offset + loaded_union.size;
433434}
434435
436fn classifySystemVArray(
437 result: *[8]Class,
438 starting_byte_offset: u64,
439 array_ty: Type,
440 zcu: *Zcu,
441 target: *const std.Target,
442) u64 {
443 const field_classes = std.mem.sliceTo(&classifySystemV(array_ty.childType(zcu), zcu, target, .other), .none);
444 var byte_offset = starting_byte_offset;
445 const elem_size = array_ty.childType(zcu).abiSize(zcu);
446 for (0..@intCast(array_ty.arrayLen(zcu))) |_| {
447 for (result[@intCast(byte_offset / 8)..][0..field_classes.len], field_classes) |*result_class, field_class|
448 result_class.* = result_class.combineSystemV(field_class);
449 byte_offset += elem_size;
450 }
451 const final_byte_offset = starting_byte_offset + array_ty.abiSize(zcu);
452 assert(final_byte_offset == byte_offset);
453 return final_byte_offset;
454}
455
435456pub const zigcc = struct {
436457 pub const stack_align: ?InternPool.Alignment = null;
437458 pub const return_in_regs = true;
test/c_abi/cfuncs.c+240
......@@ -15194,6 +15194,126 @@ void c_test_struct_f32_f32_f32_f32_f32(void) {
1519415194 zig_struct_f32_f32_f32_f32_f32((struct Struct_f32_f32_f32_f32_f32){ .a = 6, .b = 7, .c = 8, .d = 9, .e = 10 }, 11);
1519515195}
1519615196
15197struct Struct_array_1_f32 {
15198 float a[1];
15199};
15200
15201struct Struct_array_1_f32 zig_ret_struct_array_1_f32(void);
15202void zig_struct_array_1_f32(struct Struct_array_1_f32, size_t);
15203
15204struct Struct_array_1_f32 c_ret_struct_array_1_f32(void) {
15205 return (struct Struct_array_1_f32){ .a = { 4 } };
15206}
15207void c_struct_array_1_f32(struct Struct_array_1_f32 s, size_t i) {
15208 assert_or_panic(s.a[0] == 5);
15209 assert_or_panic(i == 6);
15210}
15211void c_test_struct_array_1_f32(void) {
15212 struct Struct_array_1_f32 s = zig_ret_struct_array_1_f32();
15213 assert_or_panic(s.a[0] == 1);
15214 zig_struct_array_1_f32((struct Struct_array_1_f32){ .a = { 2 } }, 3);
15215}
15216
15217struct Struct_array_2_f32 {
15218 float a[2];
15219};
15220
15221struct Struct_array_2_f32 zig_ret_struct_array_2_f32(void);
15222void zig_struct_array_2_f32(struct Struct_array_2_f32, size_t);
15223
15224struct Struct_array_2_f32 c_ret_struct_array_2_f32(void) {
15225 return (struct Struct_array_2_f32){ .a = { 6, 7 } };
15226}
15227void c_struct_array_2_f32(struct Struct_array_2_f32 s, size_t i) {
15228 assert_or_panic(s.a[0] == 8);
15229 assert_or_panic(s.a[1] == 9);
15230 assert_or_panic(i == 10);
15231}
15232void c_test_struct_array_2_f32(void) {
15233 struct Struct_array_2_f32 s = zig_ret_struct_array_2_f32();
15234 assert_or_panic(s.a[0] == 1);
15235 assert_or_panic(s.a[1] == 2);
15236 zig_struct_array_2_f32((struct Struct_array_2_f32){ .a = { 3, 4 } }, 5);
15237}
15238
15239struct Struct_array_3_f32 {
15240 float a[3];
15241};
15242
15243struct Struct_array_3_f32 zig_ret_struct_array_3_f32(void);
15244void zig_struct_array_3_f32(struct Struct_array_3_f32, size_t);
15245
15246struct Struct_array_3_f32 c_ret_struct_array_3_f32(void) {
15247 return (struct Struct_array_3_f32){ .a = { 8, 9, 10 } };
15248}
15249void c_struct_array_3_f32(struct Struct_array_3_f32 s, size_t i) {
15250 assert_or_panic(s.a[0] == 11);
15251 assert_or_panic(s.a[1] == 12);
15252 assert_or_panic(s.a[2] == 13);
15253 assert_or_panic(i == 14);
15254}
15255void c_test_struct_array_3_f32(void) {
15256 struct Struct_array_3_f32 s = zig_ret_struct_array_3_f32();
15257 assert_or_panic(s.a[0] == 1);
15258 assert_or_panic(s.a[1] == 2);
15259 assert_or_panic(s.a[2] == 3);
15260 zig_struct_array_3_f32((struct Struct_array_3_f32){ .a = { 4, 5, 6 } }, 7);
15261}
15262
15263struct Struct_array_4_f32 {
15264 float a[4];
15265};
15266
15267struct Struct_array_4_f32 zig_ret_struct_array_4_f32(void);
15268void zig_struct_array_4_f32(struct Struct_array_4_f32, size_t);
15269
15270struct Struct_array_4_f32 c_ret_struct_array_4_f32(void) {
15271 return (struct Struct_array_4_f32){ .a = { 10, 11, 12, 13 } };
15272}
15273void c_struct_array_4_f32(struct Struct_array_4_f32 s, size_t i) {
15274 assert_or_panic(s.a[0] == 14);
15275 assert_or_panic(s.a[1] == 15);
15276 assert_or_panic(s.a[2] == 16);
15277 assert_or_panic(s.a[3] == 17);
15278 assert_or_panic(i == 18);
15279}
15280void c_test_struct_array_4_f32(void) {
15281 struct Struct_array_4_f32 s = zig_ret_struct_array_4_f32();
15282 assert_or_panic(s.a[0] == 1);
15283 assert_or_panic(s.a[1] == 2);
15284 assert_or_panic(s.a[2] == 3);
15285 assert_or_panic(s.a[3] == 4);
15286 zig_struct_array_4_f32((struct Struct_array_4_f32){ .a = { 5, 6, 7, 8 } }, 9);
15287}
15288
15289struct Struct_array_5_f32 {
15290 float a[5];
15291};
15292
15293struct Struct_array_5_f32 zig_ret_struct_array_5_f32(void);
15294void zig_struct_array_5_f32(struct Struct_array_5_f32, size_t);
15295
15296struct Struct_array_5_f32 c_ret_struct_array_5_f32(void) {
15297 return (struct Struct_array_5_f32){ .a = { 12, 13, 14, 15, 16 } };
15298}
15299void c_struct_array_5_f32(struct Struct_array_5_f32 s, size_t i) {
15300 assert_or_panic(s.a[0] == 17);
15301 assert_or_panic(s.a[1] == 18);
15302 assert_or_panic(s.a[2] == 19);
15303 assert_or_panic(s.a[3] == 20);
15304 assert_or_panic(s.a[4] == 21);
15305 assert_or_panic(i == 22);
15306}
15307void c_test_struct_array_5_f32(void) {
15308 struct Struct_array_5_f32 s = zig_ret_struct_array_5_f32();
15309 assert_or_panic(s.a[0] == 1);
15310 assert_or_panic(s.a[1] == 2);
15311 assert_or_panic(s.a[2] == 3);
15312 assert_or_panic(s.a[3] == 4);
15313 assert_or_panic(s.a[4] == 5);
15314 zig_struct_array_5_f32((struct Struct_array_5_f32){ .a = { 6, 7, 8, 9, 10 } }, 11);
15315}
15316
1519715317struct Struct_f32a8 {
1519815318 alignas(8) float a;
1519915319};
......@@ -15409,6 +15529,126 @@ void c_test_struct_f64_f64_f64_f64_f64(void) {
1540915529 zig_struct_f64_f64_f64_f64_f64((struct Struct_f64_f64_f64_f64_f64){ .a = 6, .b = 7, .c = 8, .d = 9, .e = 10 }, 11);
1541015530}
1541115531
15532struct Struct_array_1_f64 {
15533 double a[1];
15534};
15535
15536struct Struct_array_1_f64 zig_ret_struct_array_1_f64(void);
15537void zig_struct_array_1_f64(struct Struct_array_1_f64, size_t);
15538
15539struct Struct_array_1_f64 c_ret_struct_array_1_f64(void) {
15540 return (struct Struct_array_1_f64){ .a = { 4 } };
15541}
15542void c_struct_array_1_f64(struct Struct_array_1_f64 s, size_t i) {
15543 assert_or_panic(s.a[0] == 5);
15544 assert_or_panic(i == 6);
15545}
15546void c_test_struct_array_1_f64(void) {
15547 struct Struct_array_1_f64 s = zig_ret_struct_array_1_f64();
15548 assert_or_panic(s.a[0] == 1);
15549 zig_struct_array_1_f64((struct Struct_array_1_f64){ .a = { 2 } }, 3);
15550}
15551
15552struct Struct_array_2_f64 {
15553 double a[2];
15554};
15555
15556struct Struct_array_2_f64 zig_ret_struct_array_2_f64(void);
15557void zig_struct_array_2_f64(struct Struct_array_2_f64, size_t);
15558
15559struct Struct_array_2_f64 c_ret_struct_array_2_f64(void) {
15560 return (struct Struct_array_2_f64){ .a = { 6, 7 } };
15561}
15562void c_struct_array_2_f64(struct Struct_array_2_f64 s, size_t i) {
15563 assert_or_panic(s.a[0] == 8);
15564 assert_or_panic(s.a[1] == 9);
15565 assert_or_panic(i == 10);
15566}
15567void c_test_struct_array_2_f64(void) {
15568 struct Struct_array_2_f64 s = zig_ret_struct_array_2_f64();
15569 assert_or_panic(s.a[0] == 1);
15570 assert_or_panic(s.a[1] == 2);
15571 zig_struct_array_2_f64((struct Struct_array_2_f64){ .a = { 3, 4 } }, 5);
15572}
15573
15574struct Struct_array_3_f64 {
15575 double a[3];
15576};
15577
15578struct Struct_array_3_f64 zig_ret_struct_array_3_f64(void);
15579void zig_struct_array_3_f64(struct Struct_array_3_f64, size_t);
15580
15581struct Struct_array_3_f64 c_ret_struct_array_3_f64(void) {
15582 return (struct Struct_array_3_f64){ .a = { 8, 9, 10 } };
15583}
15584void c_struct_array_3_f64(struct Struct_array_3_f64 s, size_t i) {
15585 assert_or_panic(s.a[0] == 11);
15586 assert_or_panic(s.a[1] == 12);
15587 assert_or_panic(s.a[2] == 13);
15588 assert_or_panic(i == 14);
15589}
15590void c_test_struct_array_3_f64(void) {
15591 struct Struct_array_3_f64 s = zig_ret_struct_array_3_f64();
15592 assert_or_panic(s.a[0] == 1);
15593 assert_or_panic(s.a[1] == 2);
15594 assert_or_panic(s.a[2] == 3);
15595 zig_struct_array_3_f64((struct Struct_array_3_f64){ .a = { 4, 5, 6 } }, 7);
15596}
15597
15598struct Struct_array_4_f64 {
15599 double a[4];
15600};
15601
15602struct Struct_array_4_f64 zig_ret_struct_array_4_f64(void);
15603void zig_struct_array_4_f64(struct Struct_array_4_f64, size_t);
15604
15605struct Struct_array_4_f64 c_ret_struct_array_4_f64(void) {
15606 return (struct Struct_array_4_f64){ .a = { 10, 11, 12, 13 } };
15607}
15608void c_struct_array_4_f64(struct Struct_array_4_f64 s, size_t i) {
15609 assert_or_panic(s.a[0] == 14);
15610 assert_or_panic(s.a[1] == 15);
15611 assert_or_panic(s.a[2] == 16);
15612 assert_or_panic(s.a[3] == 17);
15613 assert_or_panic(i == 18);
15614}
15615void c_test_struct_array_4_f64(void) {
15616 struct Struct_array_4_f64 s = zig_ret_struct_array_4_f64();
15617 assert_or_panic(s.a[0] == 1);
15618 assert_or_panic(s.a[1] == 2);
15619 assert_or_panic(s.a[2] == 3);
15620 assert_or_panic(s.a[3] == 4);
15621 zig_struct_array_4_f64((struct Struct_array_4_f64){ .a = { 5, 6, 7, 8 } }, 9);
15622}
15623
15624struct Struct_array_5_f64 {
15625 double a[5];
15626};
15627
15628struct Struct_array_5_f64 zig_ret_struct_array_5_f64(void);
15629void zig_struct_array_5_f64(struct Struct_array_5_f64, size_t);
15630
15631struct Struct_array_5_f64 c_ret_struct_array_5_f64(void) {
15632 return (struct Struct_array_5_f64){ .a = { 12, 13, 14, 15, 16 } };
15633}
15634void c_struct_array_5_f64(struct Struct_array_5_f64 s, size_t i) {
15635 assert_or_panic(s.a[0] == 17);
15636 assert_or_panic(s.a[1] == 18);
15637 assert_or_panic(s.a[2] == 19);
15638 assert_or_panic(s.a[3] == 20);
15639 assert_or_panic(s.a[4] == 21);
15640 assert_or_panic(i == 22);
15641}
15642void c_test_struct_array_5_f64(void) {
15643 struct Struct_array_5_f64 s = zig_ret_struct_array_5_f64();
15644 assert_or_panic(s.a[0] == 1);
15645 assert_or_panic(s.a[1] == 2);
15646 assert_or_panic(s.a[2] == 3);
15647 assert_or_panic(s.a[3] == 4);
15648 assert_or_panic(s.a[4] == 5);
15649 zig_struct_array_5_f64((struct Struct_array_5_f64){ .a = { 6, 7, 8, 9, 10 } }, 11);
15650}
15651
1541215652struct Struct_u32_Union_u32_u32u32 {
1541315653 uint32_t a;
1541415654 union {
test/c_abi/main.zig+350
......@@ -16085,6 +16085,181 @@ test "struct f32, f32, f32, f32, f32" {
1608516085 c_test_struct_f32_f32_f32_f32_f32();
1608616086}
1608716087
16088const Struct_array_1_f32 = extern struct {
16089 a: [1]f32,
16090};
16091
16092comptime {
16093 skip: {
16094 if (builtin.cpu.arch.isWasm()) break :skip;
16095
16096 _ = struct {
16097 export fn zig_ret_struct_array_1_f32() Struct_array_1_f32 {
16098 return .{ .a = .{1} };
16099 }
16100 export fn zig_struct_array_1_f32(s: Struct_array_1_f32, i: usize) void {
16101 expect(s.a[0] == 2) catch @panic("test failure");
16102 expect(i == 3) catch @panic("test failure");
16103 }
16104 };
16105 }
16106}
16107
16108extern fn c_ret_struct_array_1_f32() Struct_array_1_f32;
16109extern fn c_struct_array_1_f32(Struct_array_1_f32, usize) void;
16110extern fn c_test_struct_array_1_f32() void;
16111
16112test "struct [1]f32" {
16113 if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest;
16114 if (builtin.cpu.arch.isArm()) return error.SkipZigTest;
16115 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16116 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16117 if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest;
16118 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
16119 if (builtin.cpu.arch.isWasm()) return error.SkipZigTest;
16120
16121 const s = c_ret_struct_array_1_f32();
16122 try expect(s.a[0] == 4);
16123 c_struct_array_1_f32(.{ .a = .{5} }, 6);
16124 c_test_struct_array_1_f32();
16125}
16126
16127const Struct_array_2_f32 = extern struct {
16128 a: [2]f32,
16129};
16130
16131export fn zig_ret_struct_array_2_f32() Struct_array_2_f32 {
16132 return .{ .a = .{ 1, 2 } };
16133}
16134export fn zig_struct_array_2_f32(s: Struct_array_2_f32, i: usize) void {
16135 expect(s.a[0] == 3) catch @panic("test failure");
16136 expect(s.a[1] == 4) catch @panic("test failure");
16137 expect(i == 5) catch @panic("test failure");
16138}
16139
16140extern fn c_ret_struct_array_2_f32() Struct_array_2_f32;
16141extern fn c_struct_array_2_f32(Struct_array_2_f32, usize) void;
16142extern fn c_test_struct_array_2_f32() void;
16143
16144test "struct [2]f32" {
16145 if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest;
16146 if (builtin.cpu.arch.isArm()) return error.SkipZigTest;
16147 if (builtin.cpu.arch == .loongarch64 and builtin.abi.float() == .hard) return error.SkipZigTest;
16148 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16149 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16150 if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest;
16151
16152 const s = c_ret_struct_array_2_f32();
16153 try expect(s.a[0] == 6);
16154 try expect(s.a[1] == 7);
16155 c_struct_array_2_f32(.{ .a = .{ 8, 9 } }, 10);
16156 c_test_struct_array_2_f32();
16157}
16158
16159const Struct_array_3_f32 = extern struct {
16160 a: [3]f32,
16161};
16162
16163export fn zig_ret_struct_array_3_f32() Struct_array_3_f32 {
16164 return .{ .a = .{ 1, 2, 3 } };
16165}
16166export fn zig_struct_array_3_f32(s: Struct_array_3_f32, i: usize) void {
16167 expect(s.a[0] == 4) catch @panic("test failure");
16168 expect(s.a[1] == 5) catch @panic("test failure");
16169 expect(s.a[2] == 6) catch @panic("test failure");
16170 expect(i == 7) catch @panic("test failure");
16171}
16172
16173extern fn c_ret_struct_array_3_f32() Struct_array_3_f32;
16174extern fn c_struct_array_3_f32(Struct_array_3_f32, usize) void;
16175extern fn c_test_struct_array_3_f32() void;
16176
16177test "struct [3]f32" {
16178 if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest;
16179 if (builtin.cpu.arch.isArm()) return error.SkipZigTest;
16180 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
16181 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16182 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16183
16184 const s = c_ret_struct_array_3_f32();
16185 try expect(s.a[0] == 8);
16186 try expect(s.a[1] == 9);
16187 try expect(s.a[2] == 10);
16188 c_struct_array_3_f32(.{ .a = .{ 11, 12, 13 } }, 14);
16189 c_test_struct_array_3_f32();
16190}
16191
16192const Struct_array_4_f32 = extern struct {
16193 a: [4]f32,
16194};
16195
16196export fn zig_ret_struct_array_4_f32() Struct_array_4_f32 {
16197 return .{ .a = .{ 1, 2, 3, 4 } };
16198}
16199export fn zig_struct_array_4_f32(s: Struct_array_4_f32, i: usize) void {
16200 expect(s.a[0] == 5) catch @panic("test failure");
16201 expect(s.a[1] == 6) catch @panic("test failure");
16202 expect(s.a[2] == 7) catch @panic("test failure");
16203 expect(s.a[3] == 8) catch @panic("test failure");
16204 expect(i == 9) catch @panic("test failure");
16205}
16206
16207extern fn c_ret_struct_array_4_f32() Struct_array_4_f32;
16208extern fn c_struct_array_4_f32(Struct_array_4_f32, usize) void;
16209extern fn c_test_struct_array_4_f32() void;
16210
16211test "struct [4]f32" {
16212 if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest;
16213 if (builtin.cpu.arch.isArm()) return error.SkipZigTest;
16214 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
16215 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16216 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16217
16218 const s = c_ret_struct_array_4_f32();
16219 try expect(s.a[0] == 10);
16220 try expect(s.a[1] == 11);
16221 try expect(s.a[2] == 12);
16222 try expect(s.a[3] == 13);
16223 c_struct_array_4_f32(.{ .a = .{ 14, 15, 16, 17 } }, 18);
16224 c_test_struct_array_4_f32();
16225}
16226
16227const Struct_array_5_f32 = extern struct {
16228 a: [5]f32,
16229};
16230
16231export fn zig_ret_struct_array_5_f32() Struct_array_5_f32 {
16232 return .{ .a = .{ 1, 2, 3, 4, 5 } };
16233}
16234export fn zig_struct_array_5_f32(s: Struct_array_5_f32, i: usize) void {
16235 expect(s.a[0] == 6) catch @panic("test failure");
16236 expect(s.a[1] == 7) catch @panic("test failure");
16237 expect(s.a[2] == 8) catch @panic("test failure");
16238 expect(s.a[3] == 9) catch @panic("test failure");
16239 expect(s.a[4] == 10) catch @panic("test failure");
16240 expect(i == 11) catch @panic("test failure");
16241}
16242
16243extern fn c_ret_struct_array_5_f32() Struct_array_5_f32;
16244extern fn c_struct_array_5_f32(Struct_array_5_f32, usize) void;
16245extern fn c_test_struct_array_5_f32() void;
16246
16247test "struct [5]f32" {
16248 if (builtin.cpu.arch.isArm()) return error.SkipZigTest;
16249 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
16250 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16251 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16252
16253 const s = c_ret_struct_array_5_f32();
16254 try expect(s.a[0] == 12);
16255 try expect(s.a[1] == 13);
16256 try expect(s.a[2] == 14);
16257 try expect(s.a[3] == 15);
16258 try expect(s.a[4] == 16);
16259 c_struct_array_5_f32(.{ .a = .{ 17, 18, 19, 20, 21 } }, 22);
16260 c_test_struct_array_5_f32();
16261}
16262
1608816263const Struct_f32a8 = extern struct {
1608916264 a: f32 align(8),
1609016265};
......@@ -16382,6 +16557,181 @@ test "struct f64, f64, f64, f64, f64" {
1638216557 c_test_struct_f64_f64_f64_f64_f64();
1638316558}
1638416559
16560const Struct_array_1_f64 = extern struct {
16561 a: [1]f64,
16562};
16563
16564comptime {
16565 skip: {
16566 if (builtin.cpu.arch.isWasm()) break :skip;
16567
16568 _ = struct {
16569 export fn zig_ret_struct_array_1_f64() Struct_array_1_f64 {
16570 return .{ .a = .{1} };
16571 }
16572 export fn zig_struct_array_1_f64(s: Struct_array_1_f64, i: usize) void {
16573 expect(s.a[0] == 2) catch @panic("test failure");
16574 expect(i == 3) catch @panic("test failure");
16575 }
16576 };
16577 }
16578}
16579
16580extern fn c_ret_struct_array_1_f64() Struct_array_1_f64;
16581extern fn c_struct_array_1_f64(Struct_array_1_f64, usize) void;
16582extern fn c_test_struct_array_1_f64() void;
16583
16584test "struct [1]f64" {
16585 if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest;
16586 if (builtin.cpu.arch.isArm()) return error.SkipZigTest;
16587 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16588 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16589 if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest;
16590 if (builtin.cpu.arch == .s390x) return error.SkipZigTest;
16591 if (builtin.cpu.arch.isWasm()) return error.SkipZigTest;
16592
16593 const s = c_ret_struct_array_1_f64();
16594 try expect(s.a[0] == 4);
16595 c_struct_array_1_f64(.{ .a = .{5} }, 6);
16596 c_test_struct_array_1_f64();
16597}
16598
16599const Struct_array_2_f64 = extern struct {
16600 a: [2]f64,
16601};
16602
16603export fn zig_ret_struct_array_2_f64() Struct_array_2_f64 {
16604 return .{ .a = .{ 1, 2 } };
16605}
16606export fn zig_struct_array_2_f64(s: Struct_array_2_f64, i: usize) void {
16607 expect(s.a[0] == 3) catch @panic("test failure");
16608 expect(s.a[1] == 4) catch @panic("test failure");
16609 expect(i == 5) catch @panic("test failure");
16610}
16611
16612extern fn c_ret_struct_array_2_f64() Struct_array_2_f64;
16613extern fn c_struct_array_2_f64(Struct_array_2_f64, usize) void;
16614extern fn c_test_struct_array_2_f64() void;
16615
16616test "struct [2]f64" {
16617 if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest;
16618 if (builtin.cpu.arch.isArm()) return error.SkipZigTest;
16619 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
16620 if (builtin.cpu.arch == .loongarch64 and builtin.abi.float() == .hard) return error.SkipZigTest;
16621 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16622 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16623 if (builtin.cpu.arch.isRISCV()) return error.SkipZigTest;
16624
16625 const s = c_ret_struct_array_2_f64();
16626 try expect(s.a[0] == 6);
16627 try expect(s.a[1] == 7);
16628 c_struct_array_2_f64(.{ .a = .{ 8, 9 } }, 10);
16629 c_test_struct_array_2_f64();
16630}
16631
16632const Struct_array_3_f64 = extern struct {
16633 a: [3]f64,
16634};
16635
16636export fn zig_ret_struct_array_3_f64() Struct_array_3_f64 {
16637 return .{ .a = .{ 1, 2, 3 } };
16638}
16639export fn zig_struct_array_3_f64(s: Struct_array_3_f64, i: usize) void {
16640 expect(s.a[0] == 4) catch @panic("test failure");
16641 expect(s.a[1] == 5) catch @panic("test failure");
16642 expect(s.a[2] == 6) catch @panic("test failure");
16643 expect(i == 7) catch @panic("test failure");
16644}
16645
16646extern fn c_ret_struct_array_3_f64() Struct_array_3_f64;
16647extern fn c_struct_array_3_f64(Struct_array_3_f64, usize) void;
16648extern fn c_test_struct_array_3_f64() void;
16649
16650test "struct [3]f64" {
16651 if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest;
16652 if (builtin.cpu.arch.isArm()) return error.SkipZigTest;
16653 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
16654 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16655 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16656
16657 const s = c_ret_struct_array_3_f64();
16658 try expect(s.a[0] == 8);
16659 try expect(s.a[1] == 9);
16660 try expect(s.a[2] == 10);
16661 c_struct_array_3_f64(.{ .a = .{ 11, 12, 13 } }, 14);
16662 c_test_struct_array_3_f64();
16663}
16664
16665const Struct_array_4_f64 = extern struct {
16666 a: [4]f64,
16667};
16668
16669export fn zig_ret_struct_array_4_f64() Struct_array_4_f64 {
16670 return .{ .a = .{ 1, 2, 3, 4 } };
16671}
16672export fn zig_struct_array_4_f64(s: Struct_array_4_f64, i: usize) void {
16673 expect(s.a[0] == 5) catch @panic("test failure");
16674 expect(s.a[1] == 6) catch @panic("test failure");
16675 expect(s.a[2] == 7) catch @panic("test failure");
16676 expect(s.a[3] == 8) catch @panic("test failure");
16677 expect(i == 9) catch @panic("test failure");
16678}
16679
16680extern fn c_ret_struct_array_4_f64() Struct_array_4_f64;
16681extern fn c_struct_array_4_f64(Struct_array_4_f64, usize) void;
16682extern fn c_test_struct_array_4_f64() void;
16683
16684test "struct [4]f64" {
16685 if (builtin.cpu.arch.isAARCH64()) return error.SkipZigTest;
16686 if (builtin.cpu.arch.isArm()) return error.SkipZigTest;
16687 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
16688 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16689 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16690
16691 const s = c_ret_struct_array_4_f64();
16692 try expect(s.a[0] == 10);
16693 try expect(s.a[1] == 11);
16694 try expect(s.a[2] == 12);
16695 try expect(s.a[3] == 13);
16696 c_struct_array_4_f64(.{ .a = .{ 14, 15, 16, 17 } }, 18);
16697 c_test_struct_array_4_f64();
16698}
16699
16700const Struct_array_5_f64 = extern struct {
16701 a: [5]f64,
16702};
16703
16704export fn zig_ret_struct_array_5_f64() Struct_array_5_f64 {
16705 return .{ .a = .{ 1, 2, 3, 4, 5 } };
16706}
16707export fn zig_struct_array_5_f64(s: Struct_array_5_f64, i: usize) void {
16708 expect(s.a[0] == 6) catch @panic("test failure");
16709 expect(s.a[1] == 7) catch @panic("test failure");
16710 expect(s.a[2] == 8) catch @panic("test failure");
16711 expect(s.a[3] == 9) catch @panic("test failure");
16712 expect(s.a[4] == 10) catch @panic("test failure");
16713 expect(i == 11) catch @panic("test failure");
16714}
16715
16716extern fn c_ret_struct_array_5_f64() Struct_array_5_f64;
16717extern fn c_struct_array_5_f64(Struct_array_5_f64, usize) void;
16718extern fn c_test_struct_array_5_f64() void;
16719
16720test "struct [5]f64" {
16721 if (builtin.cpu.arch == .hexagon) return error.SkipZigTest;
16722 if (builtin.cpu.arch.isMIPS64()) return error.SkipZigTest;
16723 if (builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
16724
16725 const s = c_ret_struct_array_5_f64();
16726 try expect(s.a[0] == 12);
16727 try expect(s.a[1] == 13);
16728 try expect(s.a[2] == 14);
16729 try expect(s.a[3] == 15);
16730 try expect(s.a[4] == 16);
16731 c_struct_array_5_f64(.{ .a = .{ 17, 18, 19, 20, 21 } }, 22);
16732 c_test_struct_array_5_f64();
16733}
16734
1638516735const Struct_u32_Union_u32_u32u32 = extern struct {
1638616736 a: u32,
1638716737 b: extern union {