Skip to content

Commit

Permalink
Sema: promote smaller float types passed to variadic functions
Browse files Browse the repository at this point in the history
Closes #6854
  • Loading branch information
Vexu committed Jan 16, 2023
1 parent 3308644 commit ad79774
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 1 deletion.
14 changes: 13 additions & 1 deletion src/Sema.zig
Original file line number Diff line number Diff line change
Expand Up @@ -26067,7 +26067,8 @@ fn coerceVarArgParam(
) !Air.Inst.Ref {
if (block.is_typeof) return inst;

const coerced = switch (sema.typeOf(inst).zigTypeTag()) {
const uncasted_ty = sema.typeOf(inst);
const coerced = switch (uncasted_ty.zigTypeTag()) {
// TODO consider casting to c_int/f64 if they fit
.ComptimeInt, .ComptimeFloat => return sema.fail(
block,
Expand All @@ -26081,6 +26082,17 @@ fn coerceVarArgParam(
break :blk try sema.analyzeDeclRef(fn_decl);
},
.Array => return sema.fail(block, inst_src, "arrays must be passed by reference to variadic function", .{}),
.Float => float: {
const target = sema.mod.getTarget();
const double_bits = @import("type.zig").CType.sizeInBits(.double, target);
const inst_bits = uncasted_ty.floatBits(sema.mod.getTarget());
if (inst_bits >= double_bits) break :float inst;
switch (double_bits) {
32 => break :float try sema.coerce(block, Type.f32, inst, inst_src),
64 => break :float try sema.coerce(block, Type.f64, inst, inst_src),
else => unreachable,
}
},
else => inst,
};

Expand Down
14 changes: 14 additions & 0 deletions test/cases/f32_passed_to_variadic_fn.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
extern fn printf(format: [*:0]const u8, ...) c_int;
pub fn main() void {
var a: f64 = 2.0;
var b: f32 = 10.0;
_ = printf("f64: %f\n", a);
_ = printf("f32: %f\n", b);
}

// run
// backend=llvm
//
// f64: 2.000000
// f32: 10.000000
//

0 comments on commit ad79774

Please sign in to comment.