authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-01-16 15:40:22+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-01-17 20:28:43+02:00
loge04547642ac2d0c1cba010b6101bb30c210735cb
tree6d540eefa7ad5eba40ae7a3b30c8c44f9c433d0d
parent14f03fbd1602dae8fcaa5da42f5769422d1c4a7a

Sema: promote smaller float types passed to variadic functions

Closes #6854

2 files changed, 28 insertions(+), 1 deletions(-)

src/Sema.zig+13-1
...@@ -26067,7 +26067,8 @@ fn coerceVarArgParam(...@@ -26067,7 +26067,8 @@ fn coerceVarArgParam(
26067) !Air.Inst.Ref {26067) !Air.Inst.Ref {
26068 if (block.is_typeof) return inst;26068 if (block.is_typeof) return inst;
2606926069
26070 const coerced = switch (sema.typeOf(inst).zigTypeTag()) {26070 const uncasted_ty = sema.typeOf(inst);
26071 const coerced = switch (uncasted_ty.zigTypeTag()) {
26071 // TODO consider casting to c_int/f64 if they fit26072 // TODO consider casting to c_int/f64 if they fit
26072 .ComptimeInt, .ComptimeFloat => return sema.fail(26073 .ComptimeInt, .ComptimeFloat => return sema.fail(
26073 block,26074 block,
...@@ -26081,6 +26082,17 @@ fn coerceVarArgParam(...@@ -26081,6 +26082,17 @@ fn coerceVarArgParam(
26081 break :blk try sema.analyzeDeclRef(fn_decl);26082 break :blk try sema.analyzeDeclRef(fn_decl);
26082 },26083 },
26083 .Array => return sema.fail(block, inst_src, "arrays must be passed by reference to variadic function", .{}),26084 .Array => return sema.fail(block, inst_src, "arrays must be passed by reference to variadic function", .{}),
26085 .Float => float: {
26086 const target = sema.mod.getTarget();
26087 const double_bits = @import("type.zig").CType.sizeInBits(.double, target);
26088 const inst_bits = uncasted_ty.floatBits(sema.mod.getTarget());
26089 if (inst_bits >= double_bits) break :float inst;
26090 switch (double_bits) {
26091 32 => break :float try sema.coerce(block, Type.f32, inst, inst_src),
26092 64 => break :float try sema.coerce(block, Type.f64, inst, inst_src),
26093 else => unreachable,
26094 }
26095 },
26084 else => inst,26096 else => inst,
26085 };26097 };
2608626098
test/cases/f32_passed_to_variadic_fn.zig created+15
...@@ -0,0 +1,15 @@
1extern fn printf(format: [*:0]const u8, ...) c_int;
2pub fn main() void {
3 var a: f64 = 2.0;
4 var b: f32 = 10.0;
5 _ = printf("f64: %f\n", a);
6 _ = printf("f32: %f\n", b);
7}
8
9// run
10// backend=llvm
11// target=x86_64-linux-gnu
12//
13// f64: 2.000000
14// f32: 10.000000
15//
\ No newline at end of file