zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

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:
Msrc/Sema.zig | 10+---------
Msrc/Type.zig | 12++++++++++++
Mtest/behavior/cast.zig | 3+++
Rtest/cases/compile_errors/coerce_int_to_float.zig -> test/cases/compile_errors/coerce_large_int_to_float.zig | 0
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