mirror of
https://github.com/ziglang/zig.git
synced 2026-01-20 22:35:24 +00:00
commit
bb15e4057c
@ -440,7 +440,7 @@ pub fn build(b: *Builder) !void {
|
||||
b.enable_wine,
|
||||
enable_symlinks_windows,
|
||||
));
|
||||
test_step.dependOn(tests.addCAbiTests(b, skip_non_native));
|
||||
test_step.dependOn(tests.addCAbiTests(b, skip_non_native, skip_release));
|
||||
test_step.dependOn(tests.addLinkTests(b, test_filter, modes, enable_macos_sdk, skip_stage2_tests, enable_symlinks_windows));
|
||||
test_step.dependOn(tests.addStackTraceTests(b, test_filter, modes));
|
||||
test_step.dependOn(tests.addCliTests(b, test_filter, modes));
|
||||
|
||||
@ -5,7 +5,19 @@ const assert = std.debug.assert;
|
||||
const Register = @import("bits.zig").Register;
|
||||
const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager;
|
||||
|
||||
pub const Class = enum { integer, sse, sseup, x87, x87up, complex_x87, memory, none, win_i128 };
|
||||
pub const Class = enum {
|
||||
integer,
|
||||
sse,
|
||||
sseup,
|
||||
x87,
|
||||
x87up,
|
||||
complex_x87,
|
||||
memory,
|
||||
none,
|
||||
win_i128,
|
||||
float,
|
||||
float_combine,
|
||||
};
|
||||
|
||||
pub fn classifyWindows(ty: Type, target: Target) Class {
|
||||
// https://docs.microsoft.com/en-gb/cpp/build/x64-calling-convention?view=vs-2017
|
||||
@ -112,7 +124,20 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {
|
||||
return result;
|
||||
},
|
||||
.Float => switch (ty.floatBits(target)) {
|
||||
16, 32, 64 => {
|
||||
16 => {
|
||||
if (ctx == .other) {
|
||||
result[0] = .memory;
|
||||
} else {
|
||||
// TODO clang doesn't allow __fp16 as .ret or .arg
|
||||
result[0] = .sse;
|
||||
}
|
||||
return result;
|
||||
},
|
||||
32 => {
|
||||
result[0] = .float;
|
||||
return result;
|
||||
},
|
||||
64 => {
|
||||
result[0] = .sse;
|
||||
return result;
|
||||
},
|
||||
@ -120,11 +145,15 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {
|
||||
// "Arguments of types__float128, _Decimal128 and__m128 are
|
||||
// split into two halves. The least significant ones belong
|
||||
// to class SSE, the most significant one to class SSEUP."
|
||||
if (ctx == .other) {
|
||||
result[0] = .memory;
|
||||
return result;
|
||||
}
|
||||
result[0] = .sse;
|
||||
result[1] = .sseup;
|
||||
return result;
|
||||
},
|
||||
else => {
|
||||
80 => {
|
||||
// "The 64-bit mantissa of arguments of type long double
|
||||
// belongs to classX87, the 16-bit exponent plus 6 bytes
|
||||
// of padding belongs to class X87UP."
|
||||
@ -132,6 +161,7 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {
|
||||
result[1] = .x87up;
|
||||
return result;
|
||||
},
|
||||
else => unreachable,
|
||||
},
|
||||
.Vector => {
|
||||
const elem_ty = ty.childType();
|
||||
@ -238,6 +268,9 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {
|
||||
combine: {
|
||||
// "If both classes are equal, this is the resulting class."
|
||||
if (result[result_i] == field_class[0]) {
|
||||
if (result[result_i] == .float) {
|
||||
result[result_i] = .float_combine;
|
||||
}
|
||||
break :combine;
|
||||
}
|
||||
|
||||
|
||||
@ -10395,7 +10395,12 @@ fn firstParamSRet(fn_info: Type.Payload.Function.Data, target: std.Target) bool
|
||||
.mips, .mipsel => return false,
|
||||
.x86_64 => switch (target.os.tag) {
|
||||
.windows => return x86_64_abi.classifyWindows(fn_info.return_type, target) == .memory,
|
||||
else => return x86_64_abi.classifySystemV(fn_info.return_type, target, .ret)[0] == .memory,
|
||||
else => {
|
||||
const class = x86_64_abi.classifySystemV(fn_info.return_type, target, .ret);
|
||||
if (class[0] == .memory) return true;
|
||||
if (class[0] == .x87 and class[2] != .none) return true;
|
||||
return false;
|
||||
},
|
||||
},
|
||||
.wasm32 => return wasm_c_abi.classifyType(fn_info.return_type, target)[0] == .indirect,
|
||||
.aarch64, .aarch64_be => return aarch64_c_abi.classifyType(fn_info.return_type, target) == .memory,
|
||||
@ -10469,22 +10474,26 @@ fn lowerFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*llvm.Type {
|
||||
llvm_types_buffer[llvm_types_index] = dg.context.intType(64);
|
||||
llvm_types_index += 1;
|
||||
},
|
||||
.sse => {
|
||||
.sse, .sseup => {
|
||||
llvm_types_buffer[llvm_types_index] = dg.context.doubleType();
|
||||
llvm_types_index += 1;
|
||||
},
|
||||
.sseup => {
|
||||
llvm_types_buffer[llvm_types_index] = dg.context.doubleType();
|
||||
.float => {
|
||||
llvm_types_buffer[llvm_types_index] = dg.context.floatType();
|
||||
llvm_types_index += 1;
|
||||
},
|
||||
.float_combine => {
|
||||
llvm_types_buffer[llvm_types_index] = dg.context.floatType().vectorType(2);
|
||||
llvm_types_index += 1;
|
||||
},
|
||||
.x87 => {
|
||||
if (llvm_types_index != 0 or classes[2] != .none) {
|
||||
return dg.context.voidType();
|
||||
}
|
||||
llvm_types_buffer[llvm_types_index] = dg.context.x86FP80Type();
|
||||
llvm_types_index += 1;
|
||||
},
|
||||
.x87up => {
|
||||
llvm_types_buffer[llvm_types_index] = dg.context.x86FP80Type();
|
||||
llvm_types_index += 1;
|
||||
},
|
||||
.x87up => continue,
|
||||
.complex_x87 => {
|
||||
@panic("TODO");
|
||||
},
|
||||
@ -10689,22 +10698,25 @@ const ParamTypeIterator = struct {
|
||||
llvm_types_buffer[llvm_types_index] = dg.context.intType(64);
|
||||
llvm_types_index += 1;
|
||||
},
|
||||
.sse => {
|
||||
.sse, .sseup => {
|
||||
llvm_types_buffer[llvm_types_index] = dg.context.doubleType();
|
||||
llvm_types_index += 1;
|
||||
},
|
||||
.sseup => {
|
||||
llvm_types_buffer[llvm_types_index] = dg.context.doubleType();
|
||||
.float => {
|
||||
llvm_types_buffer[llvm_types_index] = dg.context.floatType();
|
||||
llvm_types_index += 1;
|
||||
},
|
||||
.float_combine => {
|
||||
llvm_types_buffer[llvm_types_index] = dg.context.floatType().vectorType(2);
|
||||
llvm_types_index += 1;
|
||||
},
|
||||
.x87 => {
|
||||
llvm_types_buffer[llvm_types_index] = dg.context.x86FP80Type();
|
||||
llvm_types_index += 1;
|
||||
},
|
||||
.x87up => {
|
||||
llvm_types_buffer[llvm_types_index] = dg.context.x86FP80Type();
|
||||
llvm_types_index += 1;
|
||||
it.zig_index += 1;
|
||||
it.llvm_index += 1;
|
||||
it.byval_attr = true;
|
||||
return .byref;
|
||||
},
|
||||
.x87up => unreachable,
|
||||
.complex_x87 => {
|
||||
@panic("TODO");
|
||||
},
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
void zig_panic();
|
||||
void zig_panic(void);
|
||||
|
||||
static void assert_or_panic(bool ok) {
|
||||
if (!ok) {
|
||||
@ -60,6 +60,54 @@ static void assert_or_panic(bool ok) {
|
||||
# define ZIG_NO_COMPLEX
|
||||
#endif
|
||||
|
||||
#ifdef __x86_64__
|
||||
#define ZIG_NO_RAW_F16
|
||||
#endif
|
||||
|
||||
#ifdef __i386__
|
||||
#define ZIG_NO_RAW_F16
|
||||
#endif
|
||||
|
||||
#ifdef __mips__
|
||||
#define ZIG_NO_RAW_F16
|
||||
#endif
|
||||
|
||||
#ifdef __riscv
|
||||
#define ZIG_NO_RAW_F16
|
||||
#endif
|
||||
|
||||
#ifdef __wasm__
|
||||
#define ZIG_NO_RAW_F16
|
||||
#endif
|
||||
|
||||
#ifdef __powerpc__
|
||||
#define ZIG_NO_RAW_F16
|
||||
#endif
|
||||
|
||||
#ifdef __aarch64__
|
||||
#define ZIG_NO_F128
|
||||
#endif
|
||||
|
||||
#ifdef __arm__
|
||||
#define ZIG_NO_F128
|
||||
#endif
|
||||
|
||||
#ifdef __mips__
|
||||
#define ZIG_NO_F128
|
||||
#endif
|
||||
|
||||
#ifdef __riscv
|
||||
#define ZIG_NO_F128
|
||||
#endif
|
||||
|
||||
#ifdef __powerpc__
|
||||
#define ZIG_NO_F128
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define ZIG_NO_F128
|
||||
#endif
|
||||
|
||||
#ifndef ZIG_NO_I128
|
||||
struct i128 {
|
||||
__int128 value;
|
||||
@ -884,3 +932,56 @@ void c_func_ptr_byval(void *a, void *b, struct ByVal in, unsigned long c, void *
|
||||
assert_or_panic((intptr_t)d == 4);
|
||||
assert_or_panic(e == 5);
|
||||
}
|
||||
|
||||
#ifndef ZIG_NO_RAW_F16
|
||||
__fp16 c_f16(__fp16 a) {
|
||||
assert_or_panic(a == 12);
|
||||
return 34;
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
__fp16 a;
|
||||
} f16_struct;
|
||||
f16_struct c_f16_struct(f16_struct a) {
|
||||
assert_or_panic(a.a == 12);
|
||||
return (f16_struct){34};
|
||||
}
|
||||
|
||||
#if defined __x86_64__ || defined __i386__
|
||||
typedef long double f80;
|
||||
f80 c_f80(f80 a) {
|
||||
assert_or_panic((double)a == 12.34);
|
||||
return 56.78;
|
||||
}
|
||||
typedef struct {
|
||||
f80 a;
|
||||
} f80_struct;
|
||||
f80_struct c_f80_struct(f80_struct a) {
|
||||
assert_or_panic((double)a.a == 12.34);
|
||||
return (f80_struct){56.78};
|
||||
}
|
||||
typedef struct {
|
||||
f80 a;
|
||||
int b;
|
||||
} f80_extra_struct;
|
||||
f80_extra_struct c_f80_extra_struct(f80_extra_struct a) {
|
||||
assert_or_panic((double)a.a == 12.34);
|
||||
assert_or_panic(a.b == 42);
|
||||
return (f80_extra_struct){56.78, 24};
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef ZIG_NO_F128
|
||||
__float128 c_f128(__float128 a) {
|
||||
assert_or_panic((double)a == 12.34);
|
||||
return 56.78;
|
||||
}
|
||||
typedef struct {
|
||||
__float128 a;
|
||||
} f128_struct;
|
||||
f128_struct c_f128_struct(f128_struct a) {
|
||||
assert_or_panic((double)a.a == 12.34);
|
||||
return (f128_struct){56.78};
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
//! To run all the tests on the tier 1 architecture you can use:
|
||||
//! zig build test-c-abi -fqemu
|
||||
//! To run the tests on a specific architecture:
|
||||
//! zig test -fno-stage1 -lc main.zig cfuncs.c -target mips-linux --test-cmd qemu-mips --test-cmd-bin
|
||||
//! zig test -lc main.zig cfuncs.c -target mips-linux --test-cmd qemu-mips --test-cmd-bin
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const print = std.debug.print;
|
||||
@ -13,6 +13,9 @@ const expectEqual = std.testing.expectEqual;
|
||||
const has_i128 = builtin.cpu.arch != .x86 and !builtin.cpu.arch.isARM() and
|
||||
!builtin.cpu.arch.isMIPS() and !builtin.cpu.arch.isPPC();
|
||||
|
||||
const has_f128 = builtin.cpu.arch.isX86() and !builtin.os.tag.isDarwin();
|
||||
const has_f80 = builtin.cpu.arch.isX86();
|
||||
|
||||
extern fn run_c_tests() void;
|
||||
|
||||
export fn zig_panic() noreturn {
|
||||
@ -764,6 +767,7 @@ extern fn c_float_array_struct(FloatArrayStruct) void;
|
||||
extern fn c_ret_float_array_struct() FloatArrayStruct;
|
||||
|
||||
test "Float array like struct" {
|
||||
if (builtin.cpu.arch == .x86 and builtin.mode != .Debug) return error.SkipZigTest;
|
||||
if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
|
||||
if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;
|
||||
|
||||
@ -824,7 +828,9 @@ extern fn c_big_vec(BigVec) void;
|
||||
extern fn c_ret_big_vec() BigVec;
|
||||
|
||||
test "big simd vector" {
|
||||
if (comptime builtin.cpu.arch.isMIPS() and builtin.mode != .Debug) return error.SkipZigTest;
|
||||
if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest;
|
||||
if (builtin.cpu.arch == .x86_64 and builtin.os.tag == .macos and builtin.mode != .Debug) return error.SkipZigTest;
|
||||
|
||||
c_big_vec(.{ 1, 2, 3, 4, 5, 6, 7, 8 });
|
||||
|
||||
@ -875,6 +881,8 @@ test "DC: Zig passes to C" {
|
||||
try expectOk(c_assert_DC(.{ .v1 = -0.25, .v2 = 15 }));
|
||||
}
|
||||
test "DC: Zig returns to C" {
|
||||
if (builtin.cpu.arch == .x86 and builtin.mode != .Debug) return error.SkipZigTest;
|
||||
if (comptime builtin.cpu.arch.isMIPS() and builtin.mode != .Debug) return error.SkipZigTest;
|
||||
if (comptime builtin.cpu.arch.isRISCV()) return error.SkipZigTest;
|
||||
if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;
|
||||
if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest;
|
||||
@ -888,6 +896,8 @@ test "DC: C passes to Zig" {
|
||||
try expectOk(c_send_DC());
|
||||
}
|
||||
test "DC: C returns to Zig" {
|
||||
if (builtin.cpu.arch == .x86 and builtin.mode != .Debug) return error.SkipZigTest;
|
||||
if (comptime builtin.cpu.arch.isMIPS() and builtin.mode != .Debug) return error.SkipZigTest;
|
||||
if (comptime builtin.cpu.arch.isRISCV()) return error.SkipZigTest;
|
||||
if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;
|
||||
if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest;
|
||||
@ -920,6 +930,7 @@ test "CFF: Zig passes to C" {
|
||||
try expectOk(c_assert_CFF(.{ .v1 = 39, .v2 = 0.875, .v3 = 1.0 }));
|
||||
}
|
||||
test "CFF: Zig returns to C" {
|
||||
if (builtin.cpu.arch == .x86 and builtin.mode != .Debug) return error.SkipZigTest;
|
||||
if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
|
||||
if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;
|
||||
if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest;
|
||||
@ -927,6 +938,8 @@ test "CFF: Zig returns to C" {
|
||||
}
|
||||
test "CFF: C passes to Zig" {
|
||||
if (builtin.target.cpu.arch == .x86) return error.SkipZigTest;
|
||||
if (comptime builtin.cpu.arch.isRISCV() and builtin.mode != .Debug) return error.SkipZigTest;
|
||||
if (builtin.cpu.arch == .aarch64 and builtin.mode != .Debug) return error.SkipZigTest;
|
||||
if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
|
||||
if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;
|
||||
if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest;
|
||||
@ -934,6 +947,9 @@ test "CFF: C passes to Zig" {
|
||||
try expectOk(c_send_CFF());
|
||||
}
|
||||
test "CFF: C returns to Zig" {
|
||||
if (builtin.cpu.arch == .x86 and builtin.mode != .Debug) return error.SkipZigTest;
|
||||
if (builtin.cpu.arch == .aarch64 and builtin.mode != .Debug) return error.SkipZigTest;
|
||||
if (comptime builtin.cpu.arch.isRISCV() and builtin.mode != .Debug) return error.SkipZigTest;
|
||||
if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
|
||||
if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;
|
||||
if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest;
|
||||
@ -967,6 +983,7 @@ test "PD: Zig passes to C" {
|
||||
}
|
||||
test "PD: Zig returns to C" {
|
||||
if (builtin.target.cpu.arch == .x86) return error.SkipZigTest;
|
||||
if (comptime builtin.cpu.arch.isMIPS() and builtin.mode != .Debug) return error.SkipZigTest;
|
||||
if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;
|
||||
if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest;
|
||||
try expectOk(c_assert_ret_PD());
|
||||
@ -980,6 +997,7 @@ test "PD: C passes to Zig" {
|
||||
}
|
||||
test "PD: C returns to Zig" {
|
||||
if (builtin.target.cpu.arch == .x86) return error.SkipZigTest;
|
||||
if (comptime builtin.cpu.arch.isMIPS() and builtin.mode != .Debug) return error.SkipZigTest;
|
||||
if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;
|
||||
if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest;
|
||||
try expectEqual(c_ret_PD(), .{ .v1 = null, .v2 = 0.5 });
|
||||
@ -1014,6 +1032,7 @@ extern fn c_modify_by_ref_param(ByRef) ByRef;
|
||||
|
||||
test "C function modifies by ref param" {
|
||||
if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;
|
||||
if (builtin.cpu.arch == .x86_64 and builtin.os.tag == .windows and builtin.mode != .Debug) return error.SkipZigTest;
|
||||
|
||||
const res = c_modify_by_ref_param(.{ .val = 1, .arr = undefined });
|
||||
try expect(res.val == 42);
|
||||
@ -1034,6 +1053,8 @@ const ByVal = extern struct {
|
||||
|
||||
extern fn c_func_ptr_byval(*anyopaque, *anyopaque, ByVal, c_ulong, *anyopaque, c_ulong) void;
|
||||
test "C function that takes byval struct called via function pointer" {
|
||||
if (builtin.cpu.arch == .x86 and builtin.mode != .Debug) return error.SkipZigTest;
|
||||
if (comptime builtin.cpu.arch.isMIPS() and builtin.mode != .Debug) return error.SkipZigTest;
|
||||
if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;
|
||||
|
||||
var fn_ptr = &c_func_ptr_byval;
|
||||
@ -1049,3 +1070,80 @@ test "C function that takes byval struct called via function pointer" {
|
||||
@as(c_ulong, 5),
|
||||
);
|
||||
}
|
||||
|
||||
extern fn c_f16(f16) f16;
|
||||
test "f16 bare" {
|
||||
if (!comptime builtin.cpu.arch.isAARCH64()) return error.SkipZigTest;
|
||||
|
||||
const a = c_f16(12);
|
||||
try expect(a == 34);
|
||||
}
|
||||
|
||||
const f16_struct = extern struct {
|
||||
a: f16,
|
||||
};
|
||||
extern fn c_f16_struct(f16_struct) f16_struct;
|
||||
test "f16 struct" {
|
||||
if (builtin.target.cpu.arch == .x86) return error.SkipZigTest;
|
||||
if (comptime builtin.target.cpu.arch.isMIPS()) return error.SkipZigTest;
|
||||
if (comptime builtin.target.cpu.arch.isPPC()) return error.SkipZigTest;
|
||||
if (comptime builtin.target.cpu.arch.isPPC()) return error.SkipZigTest;
|
||||
if (comptime builtin.cpu.arch.isARM() and builtin.mode != .Debug) return error.SkipZigTest;
|
||||
|
||||
const a = c_f16_struct(.{ .a = 12 });
|
||||
try expect(a.a == 34);
|
||||
}
|
||||
|
||||
extern fn c_f80(f80) f80;
|
||||
test "f80 bare" {
|
||||
if (!has_f80) return error.SkipZigTest;
|
||||
|
||||
const a = c_f80(12.34);
|
||||
try expect(@floatCast(f64, a) == 56.78);
|
||||
}
|
||||
|
||||
const f80_struct = extern struct {
|
||||
a: f80,
|
||||
};
|
||||
extern fn c_f80_struct(f80_struct) f80_struct;
|
||||
test "f80 struct" {
|
||||
if (!has_f80) return error.SkipZigTest;
|
||||
if (builtin.target.cpu.arch == .x86) return error.SkipZigTest;
|
||||
if (builtin.mode != .Debug) return error.SkipZigTest;
|
||||
|
||||
const a = c_f80_struct(.{ .a = 12.34 });
|
||||
try expect(@floatCast(f64, a.a) == 56.78);
|
||||
}
|
||||
|
||||
const f80_extra_struct = extern struct {
|
||||
a: f80,
|
||||
b: c_int,
|
||||
};
|
||||
extern fn c_f80_extra_struct(f80_extra_struct) f80_extra_struct;
|
||||
test "f80 extra struct" {
|
||||
if (!has_f80) return error.SkipZigTest;
|
||||
if (builtin.target.cpu.arch == .x86) return error.SkipZigTest;
|
||||
|
||||
const a = c_f80_extra_struct(.{ .a = 12.34, .b = 42 });
|
||||
try expect(@floatCast(f64, a.a) == 56.78);
|
||||
try expect(a.b == 24);
|
||||
}
|
||||
|
||||
extern fn c_f128(f128) f128;
|
||||
test "f128 bare" {
|
||||
if (!has_f128) return error.SkipZigTest;
|
||||
|
||||
const a = c_f128(12.34);
|
||||
try expect(@floatCast(f64, a) == 56.78);
|
||||
}
|
||||
|
||||
const f128_struct = extern struct {
|
||||
a: f128,
|
||||
};
|
||||
extern fn c_f128_struct(f128_struct) f128_struct;
|
||||
test "f128 struct" {
|
||||
if (!has_f128) return error.SkipZigTest;
|
||||
|
||||
const a = c_f128_struct(.{ .a = 12.34 });
|
||||
try expect(@floatCast(f64, a.a) == 56.78);
|
||||
}
|
||||
|
||||
@ -1323,10 +1323,12 @@ const c_abi_targets = [_]CrossTarget{
|
||||
},
|
||||
};
|
||||
|
||||
pub fn addCAbiTests(b: *build.Builder, skip_non_native: bool) *build.Step {
|
||||
pub fn addCAbiTests(b: *build.Builder, skip_non_native: bool, skip_release: bool) *build.Step {
|
||||
const step = b.step("test-c-abi", "Run the C ABI tests");
|
||||
|
||||
for (c_abi_targets) |c_abi_target| {
|
||||
const modes: [2]Mode = .{ .Debug, .ReleaseFast };
|
||||
|
||||
for (modes[0 .. @as(u8, 1) + @boolToInt(!skip_release)]) |mode| for (c_abi_targets) |c_abi_target| {
|
||||
if (skip_non_native and !c_abi_target.isNative())
|
||||
continue;
|
||||
|
||||
@ -1339,14 +1341,16 @@ pub fn addCAbiTests(b: *build.Builder, skip_non_native: bool) *build.Step {
|
||||
}
|
||||
test_step.linkLibC();
|
||||
test_step.addCSourceFile("test/c_abi/cfuncs.c", &.{"-std=c99"});
|
||||
test_step.setBuildMode(mode);
|
||||
|
||||
const triple_prefix = c_abi_target.zigTriple(b.allocator) catch unreachable;
|
||||
test_step.setNamePrefix(b.fmt("{s}-{s} ", .{
|
||||
test_step.setNamePrefix(b.fmt("{s}-{s}-{s} ", .{
|
||||
"test-c-abi",
|
||||
triple_prefix,
|
||||
@tagName(mode),
|
||||
}));
|
||||
|
||||
step.dependOn(&test_step.step);
|
||||
}
|
||||
};
|
||||
return step;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user