From eee43a65aec2e2b104ff64cb23488a86437578e4 Mon Sep 17 00:00:00 2001 From: xackus <14938807+xackus@users.noreply.github.com> Date: Fri, 5 Mar 2021 20:51:19 +0100 Subject: [PATCH] add tests --- lib/std/meta.zig | 32 +++++++++++++++++++++++++++----- test/translate_c.zig | 20 ++++++++++++++++++++ 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/lib/std/meta.zig b/lib/std/meta.zig index 46d31a87c3..fd3e03bdbd 100644 --- a/lib/std/meta.zig +++ b/lib/std/meta.zig @@ -1096,7 +1096,7 @@ test "sizeof" { pub const CIntLiteralRadix = enum { decimal, octal, hexadecimal }; -fn PromoteIntLiteralReturnType(comptime SuffixType: type, comptime target: comptime_int, comptime radix: CIntLiteralRadix) type { +fn PromoteIntLiteralReturnType(comptime SuffixType: type, comptime number: comptime_int, comptime radix: CIntLiteralRadix) type { const signed_decimal = [_]type{ c_int, c_long, c_longlong }; const signed_oct_hex = [_]type{ c_int, c_uint, c_long, c_ulong, c_longlong, c_ulonglong }; const unsigned = [_]type{ c_uint, c_ulong, c_ulonglong }; @@ -1111,17 +1111,39 @@ fn PromoteIntLiteralReturnType(comptime SuffixType: type, comptime target: compt var pos = mem.indexOfScalar(type, list, SuffixType).?; while (pos < list.len) : (pos += 1) { - if (target >= math.minInt(list[pos]) and target <= math.maxInt(list[pos])) { + if (number >= math.minInt(list[pos]) and number <= math.maxInt(list[pos])) { return list[pos]; } } - @compileError("Integer literal does not fit in compatible types"); + @compileError("Integer literal is too large"); } /// Promote the type of an integer literal until it fits as C would. /// This is for translate-c and is not intended for general use. -pub fn promoteIntLiteral(comptime SuffixType: type, comptime target: comptime_int, comptime radix: CIntLiteralRadix) PromoteIntLiteralReturnType(SuffixType, target, radix) { - return target; +pub fn promoteIntLiteral( + comptime SuffixType: type, + comptime number: comptime_int, + comptime radix: CIntLiteralRadix, +) PromoteIntLiteralReturnType(SuffixType, number, radix) { + return number; +} + +test "promoteIntLiteral" { + const signed_hex = promoteIntLiteral(c_int, math.maxInt(c_int) + 1, .hexadecimal); + testing.expectEqual(c_uint, @TypeOf(signed_hex)); + + if (math.maxInt(c_longlong) == math.maxInt(c_int)) return; + + const signed_decimal = promoteIntLiteral(c_int, math.maxInt(c_int) + 1, .decimal); + const unsigned = promoteIntLiteral(c_uint, math.maxInt(c_uint) + 1, .hexadecimal); + + if (math.maxInt(c_long) > math.maxInt(c_int)) { + testing.expectEqual(c_long, @TypeOf(signed_decimal)); + testing.expectEqual(c_ulong, @TypeOf(unsigned)); + } else { + testing.expectEqual(c_longlong, @TypeOf(signed_decimal)); + testing.expectEqual(c_ulonglong, @TypeOf(unsigned)); + } } /// For a given function type, returns a tuple type which fields will diff --git a/test/translate_c.zig b/test/translate_c.zig index 6134190efb..5785d07311 100644 --- a/test/translate_c.zig +++ b/test/translate_c.zig @@ -3392,4 +3392,24 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\ unnamed_0: struct_unnamed_2, \\}; }); + + cases.add("integer literal promotion", + \\#define GUARANTEED_TO_FIT_1 1024 + \\#define GUARANTEED_TO_FIT_2 10241024L + \\#define GUARANTEED_TO_FIT_3 20482048LU + \\#define MAY_NEED_PROMOTION_1 10241024 + \\#define MAY_NEED_PROMOTION_2 307230723072L + \\#define MAY_NEED_PROMOTION_3 819281928192LU + \\#define MAY_NEED_PROMOTION_HEX 0x80000000 + \\#define MAY_NEED_PROMOTION_OCT 020000000000 + , &[_][]const u8{ + \\pub const GUARANTEED_TO_FIT_1 = @as(c_int, 1024); + \\pub const GUARANTEED_TO_FIT_2 = @as(c_long, 10241024); + \\pub const GUARANTEED_TO_FIT_3 = @as(c_ulong, 20482048); + \\pub const MAY_NEED_PROMOTION_1 = @import("std").meta.promoteIntLiteral(c_int, 10241024, .decimal); + \\pub const MAY_NEED_PROMOTION_2 = @import("std").meta.promoteIntLiteral(c_long, 307230723072, .decimal); + \\pub const MAY_NEED_PROMOTION_3 = @import("std").meta.promoteIntLiteral(c_ulong, 819281928192, .decimal); + \\pub const MAY_NEED_PROMOTION_HEX = @import("std").meta.promoteIntLiteral(c_int, 0x80000000, .hexadecimal); + \\pub const MAY_NEED_PROMOTION_OCT = @import("std").meta.promoteIntLiteral(c_int, 0o020000000000, .octal); + }); }