From d2a937838e26ad0bb380b843dee9781a96a01ef5 Mon Sep 17 00:00:00 2001 From: Banacial <50495725+Banacial@users.noreply.github.com> Date: Mon, 18 Sep 2023 12:27:32 +0200 Subject: [PATCH] std.zig.c_translation.zig: fix L suffix with sized ints Closes #15066 --- lib/std/zig/c_translation.zig | 39 +++++++++++++++++++++++----- test/behavior/translate_c_macros.h | 5 +++- test/behavior/translate_c_macros.zig | 5 ++++ 3 files changed, 42 insertions(+), 7 deletions(-) diff --git a/lib/std/zig/c_translation.zig b/lib/std/zig/c_translation.zig index 2e7bb61df6..9a700a7a97 100644 --- a/lib/std/zig/c_translation.zig +++ b/lib/std/zig/c_translation.zig @@ -384,16 +384,16 @@ pub const Macros = struct { } fn L_SUFFIX_ReturnType(comptime number: anytype) type { - switch (@TypeOf(number)) { - comptime_int => return @TypeOf(promoteIntLiteral(c_long, number, .decimal)), - comptime_float => return c_longdouble, + switch (@typeInfo(@TypeOf(number))) { + .Int, .ComptimeInt => return @TypeOf(promoteIntLiteral(c_long, number, .decimal)), + .Float, .ComptimeFloat => return c_longdouble, else => @compileError("Invalid value for L suffix"), } } pub fn L_SUFFIX(comptime number: anytype) L_SUFFIX_ReturnType(number) { - switch (@TypeOf(number)) { - comptime_int => return promoteIntLiteral(c_long, number, .decimal), - comptime_float => @compileError("TODO: c_longdouble initialization from comptime_float not supported"), + switch (@typeInfo(@TypeOf(number))) { + .Int, .ComptimeInt => return promoteIntLiteral(c_long, number, .decimal), + .Float, .ComptimeFloat => @compileError("TODO: c_longdouble initialization from comptime_float not supported"), else => @compileError("Invalid value for L suffix"), } } @@ -644,3 +644,30 @@ test "CAST_OR_CALL calling" { try testing.expectEqual(Helper.identity(@as(c_uint, 100)), Macros.CAST_OR_CALL(Helper.identity, @as(c_uint, 100))); } + +test "Extended C ABI casting" { + if (math.maxInt(c_long) > math.maxInt(c_char)) { + try testing.expect(@TypeOf(Macros.L_SUFFIX(@as(c_char, math.maxInt(c_char) - 1))) == c_long); // c_char + } + if (math.maxInt(c_long) > math.maxInt(c_short)) { + try testing.expect(@TypeOf(Macros.L_SUFFIX(@as(c_short, math.maxInt(c_short) - 1))) == c_long); // c_short + } + + if (math.maxInt(c_long) > math.maxInt(c_ushort)) { + try testing.expect(@TypeOf(Macros.L_SUFFIX(@as(c_ushort, math.maxInt(c_ushort) - 1))) == c_long); //c_ushort + } + + if (math.maxInt(c_long) > math.maxInt(c_int)) { + try testing.expect(@TypeOf(Macros.L_SUFFIX(@as(c_int, math.maxInt(c_int) - 1))) == c_long); // c_int + } + + if (math.maxInt(c_long) > math.maxInt(c_uint)) { + try testing.expect(@TypeOf(Macros.L_SUFFIX(@as(c_uint, math.maxInt(c_uint) - 1))) == c_long); // c_uint + try testing.expect(@TypeOf(Macros.L_SUFFIX(math.maxInt(c_uint) + 1)) == c_long); // comptime_int -> c_long + } + + if (math.maxInt(c_longlong) > math.maxInt(c_long)) { + try testing.expect(@TypeOf(Macros.L_SUFFIX(@as(c_long, math.maxInt(c_long) - 1))) == c_long); // c_long + try testing.expect(@TypeOf(Macros.L_SUFFIX(math.maxInt(c_long) + 1)) == c_longlong); // comptime_int -> c_longlong + } +} diff --git a/test/behavior/translate_c_macros.h b/test/behavior/translate_c_macros.h index 181c6cc2ad..d9ad9b682f 100644 --- a/test/behavior/translate_c_macros.h +++ b/test/behavior/translate_c_macros.h @@ -58,4 +58,7 @@ typedef _Bool uintptr_t; #define DIVIDE_ARGS(A, B) (A / B) #define REMAINDER_CONSTANT(version) (version % 10000) -#define REMAINDER_ARGS(A, B) (A % B) \ No newline at end of file +#define REMAINDER_ARGS(A, B) (A % B) + +#define LONG(x) x##L +#define X LONG(10) diff --git a/test/behavior/translate_c_macros.zig b/test/behavior/translate_c_macros.zig index 68e91bfa58..09dabb7df6 100644 --- a/test/behavior/translate_c_macros.zig +++ b/test/behavior/translate_c_macros.zig @@ -231,3 +231,8 @@ test "@typeInfo on @cImport result" { try expect(@typeInfo(h).Struct.decls.len > 1); } + +test "Macro that uses Long type concatenation casting" { + try expect((@TypeOf(h.X)) == c_long); + try expectEqual(h.X, @as(c_long, 10)); +}