@@ -436,15 +436,24 @@ pub const Macros = struct {
436436/// Integer promotion described in C11 6.3.1.1.2
437437fn PromotedIntType (comptime T : type ) type {
438438 return switch (T ) {
439- bool , u8 , i8 , c_short = > c_int ,
439+ bool , c_short = > c_int ,
440440 c_ushort = > if (@sizeOf (c_ushort ) == @sizeOf (c_int )) c_uint else c_int ,
441441 c_int , c_uint , c_long , c_ulong , c_longlong , c_ulonglong = > T ,
442- else = > if (T == comptime_int ) {
443- @compileError ("Cannot promote `" ++ @typeName (T ) ++ "`; a fixed-size number type is required" );
444- } else if (@typeInfo (T ) == .int ) {
445- @compileError ("Cannot promote `" ++ @typeName (T ) ++ "`; a C ABI type is required" );
446- } else {
447- @compileError ("Attempted to promote invalid type `" ++ @typeName (T ) ++ "`" );
442+ else = > switch (@typeInfo (T )) {
443+ .comptime_int = > @compileError ("Cannot promote `" ++ @typeName (T ) ++ "`; a fixed-size number type is required" ),
444+ // promote to c_int if it can represent all values of T
445+ .int = > | int_info | if (int_info .bits < @bitSizeOf (c_int ))
446+ c_int
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 ) ++ "`" ),
448457 },
449458 };
450459}
@@ -533,6 +542,16 @@ test "ArithmeticConversion" {
533542 try Test .checkPromotion (c_uint , c_long , c_long );
534543
535544 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 );
536555}
537556
538557pub const MacroArithmetic = struct {
0 commit comments