zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit dbc886fd04328391598880c8d5abe8443b514a02 (tree)
parent 84cdb621599373b044cef88e6b921f86f2f6fa6c
Author: Christian Fillion <contact@cfillion.ca>
Date:   Wed, 19 Feb 2025 09:17:22 -0500

translate-c: fix division and modulo of >8-bit stdint.h types in macros

Broke in c616141241047d6d6c811d43f644eb1b7d2b26ce and e64eef366c68592f6daf063a8b8f85b8626a1598

Diffstat:
Mlib/std/zig/c_translation.zig | 33++++++++++++++++++++++++++-------
Mtest/c_import/macros.zig | 9+++++++++
2 files changed, 35 insertions(+), 7 deletions(-)

diff --git a/lib/std/zig/c_translation.zig b/lib/std/zig/c_translation.zig @@ -436,15 +436,24 @@ pub const Macros = struct { /// Integer promotion described in C11 6.3.1.1.2 fn PromotedIntType(comptime T: type) type { return switch (T) { - bool, u8, i8, c_short => c_int, + bool, c_short => c_int, c_ushort => if (@sizeOf(c_ushort) == @sizeOf(c_int)) c_uint else c_int, c_int, c_uint, c_long, c_ulong, c_longlong, c_ulonglong => T, - else => if (T == comptime_int) { - @compileError("Cannot promote `" ++ @typeName(T) ++ "`; a fixed-size number type is required"); - } else if (@typeInfo(T) == .int) { - @compileError("Cannot promote `" ++ @typeName(T) ++ "`; a C ABI type is required"); - } else { - @compileError("Attempted to promote invalid type `" ++ @typeName(T) ++ "`"); + else => switch (@typeInfo(T)) { + .comptime_int => @compileError("Cannot promote `" ++ @typeName(T) ++ "`; a fixed-size number type is required"), + // promote to c_int if it can represent all values of T + .int => |int_info| if (int_info.bits < @bitSizeOf(c_int)) + c_int + // otherwise, restore the original C type + else if (int_info.bits == @bitSizeOf(c_int)) + if (int_info.signedness == .unsigned) c_uint else c_int + else if (int_info.bits <= @bitSizeOf(c_long)) + if (int_info.signedness == .unsigned) c_ulong else c_long + else if (int_info.bits <= @bitSizeOf(c_longlong)) + if (int_info.signedness == .unsigned) c_ulonglong else c_longlong + else + @compileError("Cannot promote `" ++ @typeName(T) ++ "`; a C ABI type is required"), + else => @compileError("Attempted to promote invalid type `" ++ @typeName(T) ++ "`"), }, }; } @@ -533,6 +542,16 @@ test "ArithmeticConversion" { try Test.checkPromotion(c_uint, c_long, c_long); try Test.checkPromotion(c_ulong, c_longlong, c_ulonglong); + + // stdint.h + try Test.checkPromotion(u8, i8, c_int); + try Test.checkPromotion(u16, i16, c_int); + try Test.checkPromotion(i32, c_int, c_int); + try Test.checkPromotion(u32, c_int, c_uint); + try Test.checkPromotion(i64, c_int, c_long); + try Test.checkPromotion(u64, c_int, c_ulong); + try Test.checkPromotion(isize, c_int, c_long); + try Test.checkPromotion(usize, c_int, c_ulong); } pub const MacroArithmetic = struct { diff --git a/test/c_import/macros.zig b/test/c_import/macros.zig @@ -167,6 +167,7 @@ test "Macro that uses division operator. Issue #13162" { true, ), ); + try expectEqual( @as(c_int, 21), h.DIVIDE_ARGS( @@ -176,6 +177,14 @@ test "Macro that uses division operator. Issue #13162" { ); try expectEqual( + @as(c_uint, 21), + h.DIVIDE_ARGS( + @as(u32, 42), + @as(u32, 2), + ), + ); + + try expectEqual( @as(c_int, 21), h.DIVIDE_ARGS( @as(c_ushort, 42),