commit 89c98e200166aa3e4f5b41859f450d1307216191 (tree)
parent b4ffb402c082605c4b324e88120306fc8fb3cf32
Author: Jay Petacat <jay@jayschwa.net>
Date: Wed, 21 Jan 2026 22:57:32 -0700
Sema: fix integer coercion to `c_longdouble`
This is a follow-up to PR #30053 / commit 484cc15366.
The code previously did not handle `c_longdouble`, whose size depends on
the target. A `floatSignificandBits` helper function and a smoke test
were added.
Also added the missing max int value to the exhaustive `f16` test cases.
Diffstat:
4 files changed, 16 insertions(+), 9 deletions(-)
diff --git a/src/Sema.zig b/src/Sema.zig
@@ -27774,15 +27774,7 @@ fn coerceExtra(
}
const int_info = inst_ty.intInfo(zcu);
const int_precision = int_info.bits - @intFromBool(int_info.signedness == .signed);
- const float_precision: u8 = switch (dest_ty.toIntern()) {
- .f16_type => 11,
- .f32_type => 24,
- .f64_type => 53,
- .f80_type => 64,
- .f128_type => 113,
- else => unreachable,
- };
- if (int_precision <= float_precision) {
+ if (int_precision <= dest_ty.floatSignificandBits(target)) {
try sema.requireRuntimeBlock(block, inst_src, null);
return block.addTyOp(.float_from_int, dest_ty, inst);
}
diff --git a/src/Type.zig b/src/Type.zig
@@ -1936,6 +1936,18 @@ pub fn floatBits(ty: Type, target: *const Target) u16 {
};
}
+/// Asserts the type is a fixed-size float or comptime_float.
+pub fn floatSignificandBits(ty: Type, target: *const Target) u16 {
+ return switch (ty.floatBits(target)) {
+ 16 => 11,
+ 32 => 24,
+ 64 => 53,
+ 80 => 64,
+ 128 => 113,
+ else => unreachable,
+ };
+}
+
/// Asserts the type is a function or a function pointer.
pub fn fnReturnType(ty: Type, zcu: *const Zcu) Type {
return Type.fromInterned(zcu.intern_pool.funcTypeReturnType(ty.toIntern()));
diff --git a/test/behavior/cast.zig b/test/behavior/cast.zig
@@ -175,6 +175,7 @@ test "type coercion from int to float" {
var int: Int = std.math.minInt(Int);
while (int < std.math.maxInt(Int)) : (int += 1)
try value(Float, int);
+ try value(Float, int); // max
}
// Check that the min and max values of the integer type can safely be
@@ -202,6 +203,8 @@ test "type coercion from int to float" {
try check.edgeValues(f128, u113);
try check.edgeValues(f128, i114);
+ try check.value(c_longdouble, @as(u1, 0)); // Smoke test - size varies by target.
+
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
diff --git a/test/cases/compile_errors/coerce_int_to_float.zig b/test/cases/compile_errors/coerce_large_int_to_float.zig