diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2023-11-08 23:52:59 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-11-08 23:52:59 -0700 |
| commit | a1d688b86aeba7ab72ae12679ff04a7730931af3 (patch) | |
| tree | 610ba41fc7035e49ea24004221aed8411643a129 /src/Sema.zig | |
| parent | 997eaf6d8724fe2076195de4d6d54bf2bf880eea (diff) | |
| parent | 52d8099daeb34edc00898ef8cc34bd6f136949aa (diff) | |
| download | zig-a1d688b86aeba7ab72ae12679ff04a7730931af3.tar.gz zig-a1d688b86aeba7ab72ae12679ff04a7730931af3.zip | |
Merge pull request #17913 from jacobly0/vararg-int
Sema: implement vararg integer promotions
Diffstat (limited to 'src/Sema.zig')
| -rw-r--r-- | src/Sema.zig | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index c603fcdea4..9801ce0040 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -29419,10 +29419,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: { @@ -29436,7 +29436,33 @@ fn coerceVarArgParam( else => unreachable, } }, - else => inst, + else => if (uncasted_ty.isAbiInt(mod)) int: { + if (!try sema.validateExternType(uncasted_ty, .param_ty)) break :int inst; + 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); |
