Commit f8aecef670
Changed files (2)
src
codegen
test
behavior
src/codegen/c.zig
@@ -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;
}
test/behavior/var_args.zig
@@ -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)));