aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/compiler_rt.zig51
-rw-r--r--lib/compiler_rt/ceil.zig11
-rw-r--r--lib/compiler_rt/cos.zig11
-rw-r--r--lib/compiler_rt/exp.zig11
-rw-r--r--lib/compiler_rt/exp2.zig11
-rw-r--r--lib/compiler_rt/fabs.zig11
-rw-r--r--lib/compiler_rt/floor.zig11
-rw-r--r--lib/compiler_rt/fma.zig11
-rw-r--r--lib/compiler_rt/fmax.zig11
-rw-r--r--lib/compiler_rt/fmin.zig11
-rw-r--r--lib/compiler_rt/fmod.zig11
-rw-r--r--lib/compiler_rt/log.zig11
-rw-r--r--lib/compiler_rt/log10.zig11
-rw-r--r--lib/compiler_rt/log2.zig11
-rw-r--r--lib/compiler_rt/round.zig11
-rw-r--r--lib/compiler_rt/sin.zig11
-rw-r--r--lib/compiler_rt/sincos.zig11
-rw-r--r--lib/compiler_rt/sqrt.zig11
-rw-r--r--lib/compiler_rt/tan.zig11
-rw-r--r--lib/compiler_rt/trunc.zig11
-rw-r--r--src/Sema.zig9
-rw-r--r--src/stage1/ir.cpp6
-rw-r--r--test/behavior/cast.zig20
23 files changed, 271 insertions, 24 deletions
diff --git a/lib/compiler_rt.zig b/lib/compiler_rt.zig
index 638bbcc695..fdf5940702 100644
--- a/lib/compiler_rt.zig
+++ b/lib/compiler_rt.zig
@@ -724,25 +724,25 @@ comptime {
@export(_aullrem, .{ .name = "\x01__aullrem", .linkage = strong_linkage });
}
- mathExport("ceil", @import("./compiler_rt/ceil.zig"), true);
- mathExport("cos", @import("./compiler_rt/cos.zig"), true);
- mathExport("exp", @import("./compiler_rt/exp.zig"), true);
- mathExport("exp2", @import("./compiler_rt/exp2.zig"), true);
- mathExport("fabs", @import("./compiler_rt/fabs.zig"), true);
- mathExport("floor", @import("./compiler_rt/floor.zig"), true);
- mathExport("fma", @import("./compiler_rt/fma.zig"), true);
- mathExport("fmax", @import("./compiler_rt/fmax.zig"), true);
- mathExport("fmin", @import("./compiler_rt/fmin.zig"), true);
- mathExport("fmod", @import("./compiler_rt/fmod.zig"), true);
- mathExport("log", @import("./compiler_rt/log.zig"), true);
- mathExport("log10", @import("./compiler_rt/log10.zig"), true);
- mathExport("log2", @import("./compiler_rt/log2.zig"), true);
- mathExport("round", @import("./compiler_rt/round.zig"), true);
- mathExport("sin", @import("./compiler_rt/sin.zig"), true);
- mathExport("sincos", @import("./compiler_rt/sincos.zig"), true);
- mathExport("sqrt", @import("./compiler_rt/sqrt.zig"), true);
- mathExport("tan", @import("./compiler_rt/tan.zig"), false);
- mathExport("trunc", @import("./compiler_rt/trunc.zig"), true);
+ mathExport("ceil", @import("./compiler_rt/ceil.zig"));
+ mathExport("cos", @import("./compiler_rt/cos.zig"));
+ mathExport("exp", @import("./compiler_rt/exp.zig"));
+ mathExport("exp2", @import("./compiler_rt/exp2.zig"));
+ mathExport("fabs", @import("./compiler_rt/fabs.zig"));
+ mathExport("floor", @import("./compiler_rt/floor.zig"));
+ mathExport("fma", @import("./compiler_rt/fma.zig"));
+ mathExport("fmax", @import("./compiler_rt/fmax.zig"));
+ mathExport("fmin", @import("./compiler_rt/fmin.zig"));
+ mathExport("fmod", @import("./compiler_rt/fmod.zig"));
+ mathExport("log", @import("./compiler_rt/log.zig"));
+ mathExport("log10", @import("./compiler_rt/log10.zig"));
+ mathExport("log2", @import("./compiler_rt/log2.zig"));
+ mathExport("round", @import("./compiler_rt/round.zig"));
+ mathExport("sin", @import("./compiler_rt/sin.zig"));
+ mathExport("sincos", @import("./compiler_rt/sincos.zig"));
+ mathExport("sqrt", @import("./compiler_rt/sqrt.zig"));
+ mathExport("tan", @import("./compiler_rt/tan.zig"));
+ mathExport("trunc", @import("./compiler_rt/trunc.zig"));
if (arch.isSPARC()) {
// SPARC systems use a different naming scheme
@@ -825,7 +825,7 @@ comptime {
}
}
-inline fn mathExport(double_name: []const u8, comptime import: type, is_standard: bool) void {
+inline fn mathExport(double_name: []const u8, comptime import: type) void {
const half_name = "__" ++ double_name ++ "h";
const half_fn = @field(import, half_name);
const float_name = double_name ++ "f";
@@ -853,9 +853,12 @@ inline fn mathExport(double_name: []const u8, comptime import: type, is_standard
.{ f128, quad_fn },
};
- // Weak aliases don't work on Windows, so we avoid exporting the `l` alias
- // on this platform for functions we know will collide.
- if (builtin.os.tag != .windows or !builtin.link_libc or !is_standard) {
+ if (builtin.os.tag == .windows) {
+ // Weak aliases don't work on Windows, so we have to provide the 'l' variants
+ // as additional function definitions that jump to the real definition.
+ const long_double_fn = @field(import, long_double_name);
+ @export(long_double_fn, .{ .name = long_double_name, .linkage = linkage });
+ } else {
inline for (pairs) |pair| {
const F = pair[0];
const func = pair[1];
@@ -865,7 +868,7 @@ inline fn mathExport(double_name: []const u8, comptime import: type, is_standard
}
}
- if (is_ppc and is_standard) {
+ if (is_ppc) {
// LLVM PPC backend lowers f128 ops with the suffix `f128` instead of `l`.
@export(quad_fn, .{ .name = double_name ++ "f128", .linkage = linkage });
}
diff --git a/lib/compiler_rt/ceil.zig b/lib/compiler_rt/ceil.zig
index c7087a2c3a..06020ea8f8 100644
--- a/lib/compiler_rt/ceil.zig
+++ b/lib/compiler_rt/ceil.zig
@@ -111,6 +111,17 @@ pub fn ceilq(x: f128) callconv(.C) f128 {
}
}
+pub fn ceill(x: c_longdouble) callconv(.C) c_longdouble {
+ switch (@typeInfo(c_longdouble).Float.bits) {
+ 16 => return __ceilh(x),
+ 32 => return ceilf(x),
+ 64 => return ceil(x),
+ 80 => return __ceilx(x),
+ 128 => return ceilq(x),
+ else => @compileError("unreachable"),
+ }
+}
+
test "ceil32" {
try expect(ceilf(1.3) == 2.0);
try expect(ceilf(-1.3) == -1.0);
diff --git a/lib/compiler_rt/cos.zig b/lib/compiler_rt/cos.zig
index 957e5f9c91..e01f458243 100644
--- a/lib/compiler_rt/cos.zig
+++ b/lib/compiler_rt/cos.zig
@@ -107,6 +107,17 @@ pub fn cosq(a: f128) callconv(.C) f128 {
return cos(@floatCast(f64, a));
}
+pub fn cosl(x: c_longdouble) callconv(.C) c_longdouble {
+ switch (@typeInfo(c_longdouble).Float.bits) {
+ 16 => return __cosh(x),
+ 32 => return cosf(x),
+ 64 => return cos(x),
+ 80 => return __cosx(x),
+ 128 => return cosq(x),
+ else => @compileError("unreachable"),
+ }
+}
+
test "cos32" {
const epsilon = 0.00001;
diff --git a/lib/compiler_rt/exp.zig b/lib/compiler_rt/exp.zig
index 0f129dfd4c..a2c5d0e550 100644
--- a/lib/compiler_rt/exp.zig
+++ b/lib/compiler_rt/exp.zig
@@ -182,6 +182,17 @@ pub fn expq(a: f128) callconv(.C) f128 {
return exp(@floatCast(f64, a));
}
+pub fn expl(x: c_longdouble) callconv(.C) c_longdouble {
+ switch (@typeInfo(c_longdouble).Float.bits) {
+ 16 => return __exph(x),
+ 32 => return expf(x),
+ 64 => return exp(x),
+ 80 => return __expx(x),
+ 128 => return expq(x),
+ else => @compileError("unreachable"),
+ }
+}
+
test "exp32" {
const epsilon = 0.000001;
diff --git a/lib/compiler_rt/exp2.zig b/lib/compiler_rt/exp2.zig
index 53432a831d..cbcb53c99f 100644
--- a/lib/compiler_rt/exp2.zig
+++ b/lib/compiler_rt/exp2.zig
@@ -149,6 +149,17 @@ pub fn exp2q(x: f128) callconv(.C) f128 {
return exp2(@floatCast(f64, x));
}
+pub fn exp2l(x: c_longdouble) callconv(.C) c_longdouble {
+ switch (@typeInfo(c_longdouble).Float.bits) {
+ 16 => return __exp2h(x),
+ 32 => return exp2f(x),
+ 64 => return exp2(x),
+ 80 => return __exp2x(x),
+ 128 => return exp2q(x),
+ else => @compileError("unreachable"),
+ }
+}
+
const exp2ft = [_]f64{
0x1.6a09e667f3bcdp-1,
0x1.7a11473eb0187p-1,
diff --git a/lib/compiler_rt/fabs.zig b/lib/compiler_rt/fabs.zig
index fbef81fc9a..396fdd46b7 100644
--- a/lib/compiler_rt/fabs.zig
+++ b/lib/compiler_rt/fabs.zig
@@ -20,6 +20,17 @@ pub fn fabsq(a: f128) callconv(.C) f128 {
return generic_fabs(a);
}
+pub fn fabsl(x: c_longdouble) callconv(.C) c_longdouble {
+ switch (@typeInfo(c_longdouble).Float.bits) {
+ 16 => return __fabsh(x),
+ 32 => return fabsf(x),
+ 64 => return fabs(x),
+ 80 => return __fabsx(x),
+ 128 => return fabsq(x),
+ else => @compileError("unreachable"),
+ }
+}
+
inline fn generic_fabs(x: anytype) @TypeOf(x) {
const T = @TypeOf(x);
const TBits = std.meta.Int(.unsigned, @typeInfo(T).Float.bits);
diff --git a/lib/compiler_rt/floor.zig b/lib/compiler_rt/floor.zig
index f6df164b58..783898fca7 100644
--- a/lib/compiler_rt/floor.zig
+++ b/lib/compiler_rt/floor.zig
@@ -141,6 +141,17 @@ pub fn floorq(x: f128) callconv(.C) f128 {
}
}
+pub fn floorl(x: c_longdouble) callconv(.C) c_longdouble {
+ switch (@typeInfo(c_longdouble).Float.bits) {
+ 16 => return __floorh(x),
+ 32 => return floorf(x),
+ 64 => return floor(x),
+ 80 => return __floorx(x),
+ 128 => return floorq(x),
+ else => @compileError("unreachable"),
+ }
+}
+
test "floor16" {
try expect(__floorh(1.3) == 1.0);
try expect(__floorh(-1.3) == -2.0);
diff --git a/lib/compiler_rt/fma.zig b/lib/compiler_rt/fma.zig
index 4c603bf095..7a39a4c9a0 100644
--- a/lib/compiler_rt/fma.zig
+++ b/lib/compiler_rt/fma.zig
@@ -135,6 +135,17 @@ pub fn fmaq(x: f128, y: f128, z: f128) callconv(.C) f128 {
}
}
+pub fn fmal(x: c_longdouble, y: c_longdouble, z: c_longdouble) callconv(.C) c_longdouble {
+ switch (@typeInfo(c_longdouble).Float.bits) {
+ 16 => return __fmah(x, y, z),
+ 32 => return fmaf(x, y, z),
+ 64 => return fma(x, y, z),
+ 80 => return __fmax(x, y, z),
+ 128 => return fmaq(x, y, z),
+ else => @compileError("unreachable"),
+ }
+}
+
const dd = struct {
hi: f64,
lo: f64,
diff --git a/lib/compiler_rt/fmax.zig b/lib/compiler_rt/fmax.zig
index a5bd68cd74..defc935afc 100644
--- a/lib/compiler_rt/fmax.zig
+++ b/lib/compiler_rt/fmax.zig
@@ -21,6 +21,17 @@ pub fn fmaxq(x: f128, y: f128) callconv(.C) f128 {
return generic_fmax(f128, x, y);
}
+pub fn fmaxl(x: c_longdouble, y: c_longdouble) callconv(.C) c_longdouble {
+ switch (@typeInfo(c_longdouble).Float.bits) {
+ 16 => return __fmaxh(x, y),
+ 32 => return fmaxf(x, y),
+ 64 => return fmax(x, y),
+ 80 => return __fmaxx(x, y),
+ 128 => return fmaxq(x, y),
+ else => @compileError("unreachable"),
+ }
+}
+
inline fn generic_fmax(comptime T: type, x: T, y: T) T {
if (math.isNan(x))
return y;
diff --git a/lib/compiler_rt/fmin.zig b/lib/compiler_rt/fmin.zig
index cc4dbf082b..e93300bd4b 100644
--- a/lib/compiler_rt/fmin.zig
+++ b/lib/compiler_rt/fmin.zig
@@ -21,6 +21,17 @@ pub fn fminq(x: f128, y: f128) callconv(.C) f128 {
return generic_fmin(f128, x, y);
}
+pub fn fminl(x: c_longdouble, y: c_longdouble) callconv(.C) c_longdouble {
+ switch (@typeInfo(c_longdouble).Float.bits) {
+ 16 => return __fminh(x, y),
+ 32 => return fminf(x, y),
+ 64 => return fmin(x, y),
+ 80 => return __fminx(x, y),
+ 128 => return fminq(x, y),
+ else => @compileError("unreachable"),
+ }
+}
+
inline fn generic_fmin(comptime T: type, x: T, y: T) T {
if (math.isNan(x))
return y;
diff --git a/lib/compiler_rt/fmod.zig b/lib/compiler_rt/fmod.zig
index 28e0df3d6b..5d413ca37d 100644
--- a/lib/compiler_rt/fmod.zig
+++ b/lib/compiler_rt/fmod.zig
@@ -237,6 +237,17 @@ pub fn fmodq(a: f128, b: f128) callconv(.C) f128 {
return amod;
}
+pub fn fmodl(a: c_longdouble, b: c_longdouble) callconv(.C) c_longdouble {
+ switch (@typeInfo(c_longdouble).Float.bits) {
+ 16 => return __fmodh(a, b),
+ 32 => return fmodf(a, b),
+ 64 => return fmod(a, b),
+ 80 => return __fmodx(a, b),
+ 128 => return fmodq(a, b),
+ else => @compileError("unreachable"),
+ }
+}
+
inline fn generic_fmod(comptime T: type, x: T, y: T) T {
@setRuntimeSafety(false);
diff --git a/lib/compiler_rt/log.zig b/lib/compiler_rt/log.zig
index 8b09baac2e..6e705dae60 100644
--- a/lib/compiler_rt/log.zig
+++ b/lib/compiler_rt/log.zig
@@ -131,6 +131,17 @@ pub fn logq(a: f128) callconv(.C) f128 {
return log(@floatCast(f64, a));
}
+pub fn logl(x: c_longdouble) callconv(.C) c_longdouble {
+ switch (@typeInfo(c_longdouble).Float.bits) {
+ 16 => return __logh(x),
+ 32 => return logf(x),
+ 64 => return log(x),
+ 80 => return __logx(x),
+ 128 => return logq(x),
+ else => @compileError("unreachable"),
+ }
+}
+
test "ln32" {
const epsilon = 0.000001;
diff --git a/lib/compiler_rt/log10.zig b/lib/compiler_rt/log10.zig
index ce06d8c649..47499d2739 100644
--- a/lib/compiler_rt/log10.zig
+++ b/lib/compiler_rt/log10.zig
@@ -159,6 +159,17 @@ pub fn log10q(a: f128) callconv(.C) f128 {
return log10(@floatCast(f64, a));
}
+pub fn log10l(x: c_longdouble) callconv(.C) c_longdouble {
+ switch (@typeInfo(c_longdouble).Float.bits) {
+ 16 => return __log10h(x),
+ 32 => return log10f(x),
+ 64 => return log10(x),
+ 80 => return __log10x(x),
+ 128 => return log10q(x),
+ else => @compileError("unreachable"),
+ }
+}
+
test "log10_32" {
const epsilon = 0.000001;
diff --git a/lib/compiler_rt/log2.zig b/lib/compiler_rt/log2.zig
index 2c2d620c3d..53f35c9a80 100644
--- a/lib/compiler_rt/log2.zig
+++ b/lib/compiler_rt/log2.zig
@@ -150,6 +150,17 @@ pub fn log2q(a: f128) callconv(.C) f128 {
return math.log2(a);
}
+pub fn log2l(x: c_longdouble) callconv(.C) c_longdouble {
+ switch (@typeInfo(c_longdouble).Float.bits) {
+ 16 => return __log2h(x),
+ 32 => return log2f(x),
+ 64 => return log2(x),
+ 80 => return __log2x(x),
+ 128 => return log2q(x),
+ else => @compileError("unreachable"),
+ }
+}
+
test "log2_32" {
const epsilon = 0.000001;
diff --git a/lib/compiler_rt/round.zig b/lib/compiler_rt/round.zig
index 99201efcf8..4f3266e00c 100644
--- a/lib/compiler_rt/round.zig
+++ b/lib/compiler_rt/round.zig
@@ -123,6 +123,17 @@ pub fn roundq(x_: f128) callconv(.C) f128 {
}
}
+pub fn roundl(x: c_longdouble) callconv(.C) c_longdouble {
+ switch (@typeInfo(c_longdouble).Float.bits) {
+ 16 => return __roundh(x),
+ 32 => return roundf(x),
+ 64 => return round(x),
+ 80 => return __roundx(x),
+ 128 => return roundq(x),
+ else => @compileError("unreachable"),
+ }
+}
+
test "round32" {
try expect(roundf(1.3) == 1.0);
try expect(roundf(-1.3) == -1.0);
diff --git a/lib/compiler_rt/sin.zig b/lib/compiler_rt/sin.zig
index 3d5572a59f..20259bc309 100644
--- a/lib/compiler_rt/sin.zig
+++ b/lib/compiler_rt/sin.zig
@@ -111,6 +111,17 @@ pub fn sinq(x: f128) callconv(.C) f128 {
return sin(@floatCast(f64, x));
}
+pub fn sinl(x: c_longdouble) callconv(.C) c_longdouble {
+ switch (@typeInfo(c_longdouble).Float.bits) {
+ 16 => return __sinh(x),
+ 32 => return sinf(x),
+ 64 => return sin(x),
+ 80 => return __sinx(x),
+ 128 => return sinq(x),
+ else => @compileError("unreachable"),
+ }
+}
+
test "sin32" {
const epsilon = 0.00001;
diff --git a/lib/compiler_rt/sincos.zig b/lib/compiler_rt/sincos.zig
index 31ebd0d1d0..8bc5b83ee5 100644
--- a/lib/compiler_rt/sincos.zig
+++ b/lib/compiler_rt/sincos.zig
@@ -181,6 +181,17 @@ pub fn sincosq(x: f128, r_sin: *f128, r_cos: *f128) callconv(.C) void {
r_cos.* = small_cos;
}
+pub fn sincosl(x: c_longdouble, r_sin: *c_longdouble, r_cos: *c_longdouble) callconv(.C) void {
+ switch (@typeInfo(c_longdouble).Float.bits) {
+ 16 => return __sincosh(x, r_sin, r_cos),
+ 32 => return sincosf(x, r_sin, r_cos),
+ 64 => return sincos(x, r_sin, r_cos),
+ 80 => return __sincosx(x, r_sin, r_cos),
+ 128 => return sincosq(x, r_sin, r_cos),
+ else => @compileError("unreachable"),
+ }
+}
+
const rem_pio2_generic = @compileError("TODO");
/// Ported from musl sincosl.c. Needs the following dependencies to be complete:
diff --git a/lib/compiler_rt/sqrt.zig b/lib/compiler_rt/sqrt.zig
index ba07beb86e..8d43949f99 100644
--- a/lib/compiler_rt/sqrt.zig
+++ b/lib/compiler_rt/sqrt.zig
@@ -225,6 +225,17 @@ pub fn sqrtq(x: f128) callconv(.C) f128 {
return sqrt(@floatCast(f64, x));
}
+pub fn sqrtl(x: c_longdouble) callconv(.C) c_longdouble {
+ switch (@typeInfo(c_longdouble).Float.bits) {
+ 16 => return __sqrth(x),
+ 32 => return sqrtf(x),
+ 64 => return sqrt(x),
+ 80 => return __sqrtx(x),
+ 128 => return sqrtq(x),
+ else => @compileError("unreachable"),
+ }
+}
+
test "sqrtf" {
const V = [_]f32{
0.0,
diff --git a/lib/compiler_rt/tan.zig b/lib/compiler_rt/tan.zig
index d99f00b99e..d37022d918 100644
--- a/lib/compiler_rt/tan.zig
+++ b/lib/compiler_rt/tan.zig
@@ -96,6 +96,17 @@ pub fn tanq(x: f128) callconv(.C) f128 {
return tan(@floatCast(f64, x));
}
+pub fn tanl(x: c_longdouble) callconv(.C) c_longdouble {
+ switch (@typeInfo(c_longdouble).Float.bits) {
+ 16 => return __tanh(x),
+ 32 => return tanf(x),
+ 64 => return tan(x),
+ 80 => return __tanx(x),
+ 128 => return tanq(x),
+ else => @compileError("unreachable"),
+ }
+}
+
test "tan" {
try expect(tan(@as(f32, 0.0)) == tanf(0.0));
try expect(tan(@as(f64, 0.0)) == tan(0.0));
diff --git a/lib/compiler_rt/trunc.zig b/lib/compiler_rt/trunc.zig
index 5406f9a02d..d00df60d99 100644
--- a/lib/compiler_rt/trunc.zig
+++ b/lib/compiler_rt/trunc.zig
@@ -81,6 +81,17 @@ pub fn truncq(x: f128) callconv(.C) f128 {
}
}
+pub fn truncl(x: c_longdouble) callconv(.C) c_longdouble {
+ switch (@typeInfo(c_longdouble).Float.bits) {
+ 16 => return __trunch(x),
+ 32 => return truncf(x),
+ 64 => return trunc(x),
+ 80 => return __truncx(x),
+ 128 => return truncq(x),
+ else => @compileError("unreachable"),
+ }
+}
+
test "trunc32" {
try expect(truncf(1.3) == 1.0);
try expect(truncf(-1.3) == -1.0);
diff --git a/src/Sema.zig b/src/Sema.zig
index 76edfbf2cd..2e7e5c9293 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -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;
diff --git a/src/stage1/ir.cpp b/src/stage1/ir.cpp
index 2f4e0aa0e7..62834e564d 100644
--- a/src/stage1/ir.cpp
+++ b/src/stage1/ir.cpp
@@ -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;
diff --git a/test/behavior/cast.zig b/test/behavior/cast.zig
index 416c7914e7..231fa25b2d 100644
--- a/test/behavior/cast.zig
+++ b/test/behavior/cast.zig
@@ -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);
+}