CBE: implement the future

Turns out f(...) will be supported one day.
This commit is contained in:
Jacob Young 2023-02-23 21:18:26 -05:00
parent 1f3d9f79c1
commit f8aecef670
2 changed files with 14 additions and 6 deletions

View File

@ -6876,17 +6876,16 @@ fn airCVaStart(f: *Function, inst: Air.Inst.Index) !CValue {
const inst_ty = f.air.typeOfIndex(inst);
const fn_cty = try f.typeToCType(f.object.dg.decl.?.ty, .complete);
const param_len = fn_cty.castTag(.varargs_function).?.data.param_types.len;
if (param_len == 0)
return f.fail("CBE: C requires at least one runtime argument for varargs functions", .{});
const writer = f.object.writer();
const local = try f.allocLocal(inst, inst_ty);
try writer.writeAll("va_start(*(va_list *)&");
try f.writeCValue(writer, local, .Other);
try writer.writeAll(", ");
try f.writeCValue(writer, .{ .arg = param_len - 1 }, .FunctionArgument);
if (param_len > 0) {
try writer.writeAll(", ");
try f.writeCValue(writer, .{ .arg = param_len - 1 }, .FunctionArgument);
}
try writer.writeAll(");\n");
return local;
}

View File

@ -111,6 +111,12 @@ test "simple variadic function" {
return @cVaArg(&ap, c_int);
}
fn compatible(_: c_int, ...) callconv(.C) c_int {
var ap = @cVaStart();
defer @cVaEnd(&ap);
return @cVaArg(&ap, c_int);
}
fn add(count: c_int, ...) callconv(.C) c_int {
var ap = @cVaStart();
defer @cVaEnd(&ap);
@ -123,10 +129,13 @@ test "simple variadic function" {
}
};
if (builtin.zig_backend != .stage2_c) { // C doesn't support varargs without a preceding runtime arg.
if (builtin.zig_backend != .stage2_c) {
// pre C23 doesn't support varargs without a preceding runtime arg.
try std.testing.expectEqual(@as(c_int, 0), S.simple(@as(c_int, 0)));
try std.testing.expectEqual(@as(c_int, 1024), S.simple(@as(c_int, 1024)));
}
try std.testing.expectEqual(@as(c_int, 0), S.compatible(undefined, @as(c_int, 0)));
try std.testing.expectEqual(@as(c_int, 1024), S.compatible(undefined, @as(c_int, 1024)));
try std.testing.expectEqual(@as(c_int, 0), S.add(0));
try std.testing.expectEqual(@as(c_int, 1), S.add(1, @as(c_int, 1)));
try std.testing.expectEqual(@as(c_int, 3), S.add(2, @as(c_int, 1), @as(c_int, 2)));