diff options
| author | Jacob Young <jacobly0@users.noreply.github.com> | 2023-11-07 12:11:57 -0500 |
|---|---|---|
| committer | Jacob Young <jacobly0@users.noreply.github.com> | 2023-11-08 14:43:23 -0500 |
| commit | 045a5e924ce9abe239634545b0ad35576cc2fafc (patch) | |
| tree | e3b15a212909290f52f52309b4b712ed33fd50d9 /src/Sema.zig | |
| parent | a70d8d29d5895a8b44a86e8f065ee3ee59c9bfe8 (diff) | |
| download | zig-045a5e924ce9abe239634545b0ad35576cc2fafc.tar.gz zig-045a5e924ce9abe239634545b0ad35576cc2fafc.zip | |
Sema: implement vararg integer promotions
Diffstat (limited to 'src/Sema.zig')
| -rw-r--r-- | src/Sema.zig | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index 8e34c9e4dc..241f65a9a0 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -29418,10 +29418,10 @@ fn coerceVarArgParam( "integer and float literals passed to variadic function must be casted to a fixed-size number type", .{}, ), - .Fn => blk: { + .Fn => fn_ptr: { const fn_val = try sema.resolveConstDefinedValue(block, .unneeded, inst, undefined); const fn_decl = fn_val.pointerDecl(mod).?; - break :blk try sema.analyzeDeclRef(fn_decl); + break :fn_ptr try sema.analyzeDeclRef(fn_decl); }, .Array => return sema.fail(block, inst_src, "arrays must be passed by reference to variadic function", .{}), .Float => float: { @@ -29435,7 +29435,32 @@ fn coerceVarArgParam( else => unreachable, } }, - else => inst, + else => if (uncasted_ty.isAbiInt(mod)) int: { + const target = sema.mod.getTarget(); + const uncasted_info = uncasted_ty.intInfo(mod); + if (uncasted_info.bits <= target.c_type_bit_size(switch (uncasted_info.signedness) { + .signed => .int, + .unsigned => .uint, + })) break :int try sema.coerce(block, switch (uncasted_info.signedness) { + .signed => Type.c_int, + .unsigned => Type.c_uint, + }, inst, inst_src); + if (uncasted_info.bits <= target.c_type_bit_size(switch (uncasted_info.signedness) { + .signed => .long, + .unsigned => .ulong, + })) break :int try sema.coerce(block, switch (uncasted_info.signedness) { + .signed => Type.c_long, + .unsigned => Type.c_ulong, + }, inst, inst_src); + if (uncasted_info.bits <= target.c_type_bit_size(switch (uncasted_info.signedness) { + .signed => .longlong, + .unsigned => .ulonglong, + })) break :int try sema.coerce(block, switch (uncasted_info.signedness) { + .signed => Type.c_longlong, + .unsigned => Type.c_ulonglong, + }, inst, inst_src); + break :int inst; + } else inst, }; const coerced_ty = sema.typeOf(coerced); |
