aboutsummaryrefslogtreecommitdiff
path: root/src/Sema.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2023-11-08 23:52:59 -0700
committerGitHub <noreply@github.com>2023-11-08 23:52:59 -0700
commita1d688b86aeba7ab72ae12679ff04a7730931af3 (patch)
tree610ba41fc7035e49ea24004221aed8411643a129 /src/Sema.zig
parent997eaf6d8724fe2076195de4d6d54bf2bf880eea (diff)
parent52d8099daeb34edc00898ef8cc34bd6f136949aa (diff)
downloadzig-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.zig32
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);