@@ -35,15 +35,24 @@ pub fn ArithmeticConversion(comptime A: type, comptime B: type) type {
35
35
/// Integer promotion described in C11 6.3.1.1.2
36
36
fn PromotedIntType (comptime T : type ) type {
37
37
return switch (T ) {
38
- bool , u8 , i8 , c_short = > c_int ,
38
+ bool , c_short = > c_int ,
39
39
c_ushort = > if (@sizeOf (c_ushort ) == @sizeOf (c_int )) c_uint else c_int ,
40
40
c_int , c_uint , c_long , c_ulong , c_longlong , c_ulonglong = > T ,
41
- else = > if (T == comptime_int ) {
42
- @compileError ("Cannot promote `" ++ @typeName (T ) ++ "`; a fixed-size number type is required" );
43
- } else if (@typeInfo (T ) == .int ) {
44
- @compileError ("Cannot promote `" ++ @typeName (T ) ++ "`; a C ABI type is required" );
45
- } else {
46
- @compileError ("Attempted to promote invalid type `" ++ @typeName (T ) ++ "`" );
41
+ else = > switch (@typeInfo (T )) {
42
+ .comptime_int = > @compileError ("Cannot promote `" ++ @typeName (T ) ++ "`; a fixed-size number type is required" ),
43
+ // promote to c_int if it can represent all values of T
44
+ .int = > | int_info | if (int_info .bits < @bitSizeOf (c_int ))
45
+ c_int
46
+ // otherwise, restore the original C type
47
+ else if (int_info .bits == @bitSizeOf (c_int ))
48
+ if (int_info .signedness == .unsigned ) c_uint else c_int
49
+ else if (int_info .bits <= @bitSizeOf (c_long ))
50
+ if (int_info .signedness == .unsigned ) c_ulong else c_long
51
+ else if (int_info .bits <= @bitSizeOf (c_longlong ))
52
+ if (int_info .signedness == .unsigned ) c_ulonglong else c_longlong
53
+ else
54
+ @compileError ("Cannot promote `" ++ @typeName (T ) ++ "`; a C ABI type is required" ),
55
+ else = > @compileError ("Attempted to promote invalid type `" ++ @typeName (T ) ++ "`" ),
47
56
},
48
57
};
49
58
}
0 commit comments