authorgravatar for contact@cfillion.caChristian Fillion <contact@cfillion.ca> 2025-02-19 09:17:22-05:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2025-02-20 13:33:59+02:00
logdbc886fd04328391598880c8d5abe8443b514a02
treef5de50cafb856cfe5199a81bcb6b6eb033fd04d5
parent84cdb621599373b044cef88e6b921f86f2f6fa6c

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

Broke in c616141241047d6d6c811d43f644eb1b7d2b26ce and e64eef366c68592f6daf063a8b8f85b8626a1598

2 files changed, 35 insertions(+), 7 deletions(-)

lib/std/zig/c_translation.zig+26-7
...@@ -436,15 +436,24 @@ pub const Macros = struct {...@@ -436,15 +436,24 @@ pub const Macros = struct {
436/// Integer promotion described in C11 6.3.1.1.2436/// Integer promotion described in C11 6.3.1.1.2
437fn PromotedIntType(comptime T: type) type {437fn PromotedIntType(comptime T: type) type {
438 return switch (T) {438 return switch (T) {
439 bool, u8, i8, c_short => c_int,439 bool, c_short => c_int,
440 c_ushort => if (@sizeOf(c_ushort) == @sizeOf(c_int)) c_uint else c_int,440 c_ushort => if (@sizeOf(c_ushort) == @sizeOf(c_int)) c_uint else c_int,
441 c_int, c_uint, c_long, c_ulong, c_longlong, c_ulonglong => T,441 c_int, c_uint, c_long, c_ulong, c_longlong, c_ulonglong => T,
442 else => if (T == comptime_int) {442 else => switch (@typeInfo(T)) {
443 @compileError("Cannot promote `" ++ @typeName(T) ++ "`; a fixed-size number type is required");443 .comptime_int => @compileError("Cannot promote `" ++ @typeName(T) ++ "`; a fixed-size number type is required"),
444 } else if (@typeInfo(T) == .int) {444 // promote to c_int if it can represent all values of T
445 @compileError("Cannot promote `" ++ @typeName(T) ++ "`; a C ABI type is required");445 .int => |int_info| if (int_info.bits < @bitSizeOf(c_int))
446 } else {446 c_int
447 @compileError("Attempted to promote invalid type `" ++ @typeName(T) ++ "`");447 // otherwise, restore the original C type
448 else if (int_info.bits == @bitSizeOf(c_int))
449 if (int_info.signedness == .unsigned) c_uint else c_int
450 else if (int_info.bits <= @bitSizeOf(c_long))
451 if (int_info.signedness == .unsigned) c_ulong else c_long
452 else if (int_info.bits <= @bitSizeOf(c_longlong))
453 if (int_info.signedness == .unsigned) c_ulonglong else c_longlong
454 else
455 @compileError("Cannot promote `" ++ @typeName(T) ++ "`; a C ABI type is required"),
456 else => @compileError("Attempted to promote invalid type `" ++ @typeName(T) ++ "`"),
448 },457 },
449 };458 };
450}459}
...@@ -533,6 +542,16 @@ test "ArithmeticConversion" {...@@ -533,6 +542,16 @@ test "ArithmeticConversion" {
533 try Test.checkPromotion(c_uint, c_long, c_long);542 try Test.checkPromotion(c_uint, c_long, c_long);
534543
535 try Test.checkPromotion(c_ulong, c_longlong, c_ulonglong);544 try Test.checkPromotion(c_ulong, c_longlong, c_ulonglong);
545
546 // stdint.h
547 try Test.checkPromotion(u8, i8, c_int);
548 try Test.checkPromotion(u16, i16, c_int);
549 try Test.checkPromotion(i32, c_int, c_int);
550 try Test.checkPromotion(u32, c_int, c_uint);
551 try Test.checkPromotion(i64, c_int, c_long);
552 try Test.checkPromotion(u64, c_int, c_ulong);
553 try Test.checkPromotion(isize, c_int, c_long);
554 try Test.checkPromotion(usize, c_int, c_ulong);
536}555}
537556
538pub const MacroArithmetic = struct {557pub const MacroArithmetic = struct {
test/c_import/macros.zig+9
...@@ -167,6 +167,7 @@ test "Macro that uses division operator. Issue #13162" {...@@ -167,6 +167,7 @@ test "Macro that uses division operator. Issue #13162" {
167 true,167 true,
168 ),168 ),
169 );169 );
170
170 try expectEqual(171 try expectEqual(
171 @as(c_int, 21),172 @as(c_int, 21),
172 h.DIVIDE_ARGS(173 h.DIVIDE_ARGS(
...@@ -175,6 +176,14 @@ test "Macro that uses division operator. Issue #13162" {...@@ -175,6 +176,14 @@ test "Macro that uses division operator. Issue #13162" {
175 ),176 ),
176 );177 );
177178
179 try expectEqual(
180 @as(c_uint, 21),
181 h.DIVIDE_ARGS(
182 @as(u32, 42),
183 @as(u32, 2),
184 ),
185 );
186
178 try expectEqual(187 try expectEqual(
179 @as(c_int, 21),188 @as(c_int, 21),
180 h.DIVIDE_ARGS(189 h.DIVIDE_ARGS(