| ... | @@ -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.2 | 436 | /// Integer promotion described in C11 6.3.1.1.2 |
| 437 | fn PromotedIntType(comptime T: type) type { | 437 | fn 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); |
| 534 | | 543 | |
| 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 | } |
| 537 | | 556 | |
| 538 | pub const MacroArithmetic = struct { | 557 | pub const MacroArithmetic = struct { |