aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2023-07-10 10:41:19 -0700
committerGitHub <noreply@github.com>2023-07-10 10:41:19 -0700
commit2b8c1f0d4619565255b9faff2d24bc2360012552 (patch)
treebabdd081bafa95518c8ab9a21385aaa364081601 /src
parent3a30f0fa505e25c98772f9faffe5490b92773708 (diff)
parent026c63d8fe5caa30d003230b5514d8a3e274f82c (diff)
downloadzig-2b8c1f0d4619565255b9faff2d24bc2360012552.tar.gz
zig-2b8c1f0d4619565255b9faff2d24bc2360012552.zip
Merge pull request #16339 from r00ster91/ueficc
std.os.uefi: use std.os.uefi.cc instead of .C as calling convention
Diffstat (limited to 'src')
-rw-r--r--src/Sema.zig45
1 files changed, 39 insertions, 6 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index 9f2c577a0b..1bbd253b92 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -6628,7 +6628,7 @@ fn checkCallArgumentCount(
const fn_params_len = func_ty_info.param_types.len;
const args_len = total_args - @intFromBool(member_fn);
if (func_ty_info.is_var_args) {
- assert(func_ty_info.cc == .C);
+ assert(callConvSupportsVarArgs(func_ty_info.cc));
if (total_args >= fn_params_len) return func_ty;
} else if (fn_params_len == total_args) {
return func_ty;
@@ -8917,6 +8917,41 @@ fn handleExternLibName(
return sema.gpa.dupeZ(u8, lib_name);
}
+/// These are calling conventions that are confirmed to work with variadic functions.
+/// Any calling conventions not included here are either not yet verified to work with variadic
+/// functions or there are no more other calling conventions that support variadic functions.
+const calling_conventions_supporting_var_args = [_]std.builtin.CallingConvention{
+ .C,
+};
+fn callConvSupportsVarArgs(cc: std.builtin.CallingConvention) bool {
+ return for (calling_conventions_supporting_var_args) |supported_cc| {
+ if (cc == supported_cc) return true;
+ } else false;
+}
+fn checkCallConvSupportsVarArgs(sema: *Sema, block: *Block, src: LazySrcLoc, cc: std.builtin.CallingConvention) CompileError!void {
+ const CallingConventionsSupportingVarArgsList = struct {
+ pub fn format(_: @This(), comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
+ _ = fmt;
+ _ = options;
+ for (calling_conventions_supporting_var_args, 0..) |cc_inner, i| {
+ if (i != 0)
+ try writer.writeAll(", ");
+ try writer.print("'.{s}'", .{@tagName(cc_inner)});
+ }
+ }
+ };
+
+ if (!callConvSupportsVarArgs(cc)) {
+ const msg = msg: {
+ const msg = try sema.errMsg(block, src, "variadic function does not support '.{s}' calling convention", .{@tagName(cc)});
+ errdefer msg.destroy(sema.gpa);
+ try sema.errNote(block, src, msg, "supported calling conventions: {}", .{CallingConventionsSupportingVarArgsList{}});
+ break :msg msg;
+ };
+ return sema.failWithOwnedErrorMsg(msg);
+ }
+}
+
const FuncLinkSection = union(enum) {
generic,
default,
@@ -8963,9 +8998,7 @@ fn funcCommon(
if (is_generic) {
return sema.fail(block, func_src, "generic function cannot be variadic", .{});
}
- if (cc.? != .C) {
- return sema.fail(block, cc_src, "variadic function must have 'C' calling convention", .{});
- }
+ try sema.checkCallConvSupportsVarArgs(block, cc_src, cc.?);
}
var destroy_fn_on_error = false;
@@ -20327,8 +20360,8 @@ fn zirReify(
const is_var_args = is_var_args_val.toBool();
const cc = mod.toEnum(std.builtin.CallingConvention, calling_convention_val);
- if (is_var_args and cc != .C) {
- return sema.fail(block, src, "varargs functions must have C calling convention", .{});
+ if (is_var_args) {
+ try sema.checkCallConvSupportsVarArgs(block, src, cc);
}
const alignment = alignment: {