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.
This commit is contained in:
Jay Petacat
2026-01-21 22:57:32 -07:00
parent b4ffb402c0
commit 89c98e2001
4 changed files with 16 additions and 9 deletions
+1 -9
View File
@@ -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);
}
+12
View File
@@ -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()));
+3
View File
@@ -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;