mirror of
https://github.com/ziglang/zig.git
synced 2026-01-20 22:35:24 +00:00
translate-c: fix division and modulo of >8-bit stdint.h types in macros
Broke in c616141241047d6d6c811d43f644eb1b7d2b26ce and e64eef366c68592f6daf063a8b8f85b8626a1598
This commit is contained in:
parent
84cdb62159
commit
dbc886fd04
@ -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 {
|
||||
|
||||
@ -167,6 +167,7 @@ test "Macro that uses division operator. Issue #13162" {
|
||||
true,
|
||||
),
|
||||
);
|
||||
|
||||
try expectEqual(
|
||||
@as(c_int, 21),
|
||||
h.DIVIDE_ARGS(
|
||||
@ -175,6 +176,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(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user