| author | |
| committer | |
| log | 6fde2fcd519cacdc44871fc1035b05afee072f44 |
| tree | 05f4d03603480acda6b87d01e6d325621675da7c |
| parent | 663b67783e3e140fcaf06747f4aa28b57259023c |
For example, this allows passing a `*c_longdouble` where a `*f80` is
expected, provided that `c_longdouble` maps to `f80` for this target.3 files changed, 35 insertions(+), 0 deletions(-)
src/Sema.zig+9| ... | @@ -18673,6 +18673,15 @@ fn coerceInMemoryAllowed( | ... | @@ -18673,6 +18673,15 @@ fn coerceInMemoryAllowed( |
| 18673 | } | 18673 | } |
| 18674 | } | 18674 | } |
| 18675 | 18675 | ||
| 18676 | // Differently-named floats with the same number of bits. | ||
| 18677 | if (dest_ty.zigTypeTag() == .Float and src_ty.zigTypeTag() == .Float) { | ||
| 18678 | const dest_bits = dest_ty.floatBits(target); | ||
| 18679 | const src_bits = src_ty.floatBits(target); | ||
| 18680 | if (dest_bits == src_bits) { | ||
| 18681 | return .ok; | ||
| 18682 | } | ||
| 18683 | } | ||
| 18684 | |||
| 18676 | // Pointers / Pointer-like Optionals | 18685 | // Pointers / Pointer-like Optionals |
| 18677 | var dest_buf: Type.Payload.ElemType = undefined; | 18686 | var dest_buf: Type.Payload.ElemType = undefined; |
| 18678 | var src_buf: Type.Payload.ElemType = undefined; | 18687 | var src_buf: Type.Payload.ElemType = undefined; |
src/stage1/ir.cpp+6| ... | @@ -4480,6 +4480,12 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted | ... | @@ -4480,6 +4480,12 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted |
| 4480 | return result; | 4480 | return result; |
| 4481 | } | 4481 | } |
| 4482 | 4482 | ||
| 4483 | if (wanted_type->id == ZigTypeIdFloat && actual_type->id == ZigTypeIdFloat) { | ||
| 4484 | if (wanted_type->data.floating.bit_count == actual_type->data.floating.bit_count) { | ||
| 4485 | return result; | ||
| 4486 | } | ||
| 4487 | } | ||
| 4488 | |||
| 4483 | if (wanted_type->id == ZigTypeIdVector && actual_type->id == ZigTypeIdVector) { | 4489 | if (wanted_type->id == ZigTypeIdVector && actual_type->id == ZigTypeIdVector) { |
| 4484 | if (actual_type->data.vector.len != wanted_type->data.vector.len) { | 4490 | if (actual_type->data.vector.len != wanted_type->data.vector.len) { |
| 4485 | result.id = ConstCastResultIdVectorLength; | 4491 | result.id = ConstCastResultIdVectorLength; |
test/behavior/cast.zig+20| ... | @@ -1426,3 +1426,23 @@ test "pointer to empty struct literal to mutable slice" { | ... | @@ -1426,3 +1426,23 @@ test "pointer to empty struct literal to mutable slice" { |
| 1426 | var x: []i32 = &.{}; | 1426 | var x: []i32 = &.{}; |
| 1427 | try expect(x.len == 0); | 1427 | try expect(x.len == 0); |
| 1428 | } | 1428 | } |
| 1429 | |||
| 1430 | test "coerce between pointers of compatible differently-named floats" { | ||
| 1431 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1432 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | ||
| 1433 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 1434 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1435 | |||
| 1436 | const F = switch (@typeInfo(c_longdouble).Float.bits) { | ||
| 1437 | 16 => f16, | ||
| 1438 | 32 => f32, | ||
| 1439 | 64 => f64, | ||
| 1440 | 80 => f80, | ||
| 1441 | 128 => f128, | ||
| 1442 | else => @compileError("unreachable"), | ||
| 1443 | }; | ||
| 1444 | var f1: F = 12.34; | ||
| 1445 | var f2: *c_longdouble = &f1; | ||
| 1446 | f2.* += 1; | ||
| 1447 | try expect(f1 == @as(F, 12.34) + 1); | ||
| 1448 | } |