allow in-memory coercion of differently-named floats with same bits

For example, this allows passing a `*c_longdouble` where a `*f80` is
expected, provided that `c_longdouble` maps to `f80` for this target.
This commit is contained in:
Andrew Kelley 2022-05-08 13:05:16 -07:00
parent 663b67783e
commit 6fde2fcd51
3 changed files with 35 additions and 0 deletions

View File

@ -18673,6 +18673,15 @@ fn coerceInMemoryAllowed(
}
}
// Differently-named floats with the same number of bits.
if (dest_ty.zigTypeTag() == .Float and src_ty.zigTypeTag() == .Float) {
const dest_bits = dest_ty.floatBits(target);
const src_bits = src_ty.floatBits(target);
if (dest_bits == src_bits) {
return .ok;
}
}
// Pointers / Pointer-like Optionals
var dest_buf: Type.Payload.ElemType = undefined;
var src_buf: Type.Payload.ElemType = undefined;

View File

@ -4480,6 +4480,12 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
return result;
}
if (wanted_type->id == ZigTypeIdFloat && actual_type->id == ZigTypeIdFloat) {
if (wanted_type->data.floating.bit_count == actual_type->data.floating.bit_count) {
return result;
}
}
if (wanted_type->id == ZigTypeIdVector && actual_type->id == ZigTypeIdVector) {
if (actual_type->data.vector.len != wanted_type->data.vector.len) {
result.id = ConstCastResultIdVectorLength;

View File

@ -1426,3 +1426,23 @@ test "pointer to empty struct literal to mutable slice" {
var x: []i32 = &.{};
try expect(x.len == 0);
}
test "coerce between pointers of compatible differently-named floats" {
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
const F = switch (@typeInfo(c_longdouble).Float.bits) {
16 => f16,
32 => f32,
64 => f64,
80 => f80,
128 => f128,
else => @compileError("unreachable"),
};
var f1: F = 12.34;
var f2: *c_longdouble = &f1;
f2.* += 1;
try expect(f1 == @as(F, 12.34) + 1);
}