aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRobin Voetter <robin@voetter.nl>2023-10-08 16:57:53 +0200
committerRobin Voetter <robin@voetter.nl>2023-10-15 14:00:08 +0200
commit839a93a101804bb41cb519a965dc62e3eb7deed0 (patch)
tree4e659f3f84455ee84bb5b68af03b28e9daff0426 /src
parent4f279078c8bd57e7ee47eebce2572ab25729850a (diff)
downloadzig-839a93a101804bb41cb519a965dc62e3eb7deed0.tar.gz
zig-839a93a101804bb41cb519a965dc62e3eb7deed0.zip
intern pool: fix float equality
We need to perform bitwise equality here, otherwise we get two different entries for nan values.
Diffstat (limited to 'src')
-rw-r--r--src/InternPool.zig15
1 files changed, 10 insertions, 5 deletions
diff --git a/src/InternPool.zig b/src/InternPool.zig
index 14490c21db..36a5c65deb 100644
--- a/src/InternPool.zig
+++ b/src/InternPool.zig
@@ -1556,10 +1556,10 @@ pub const Key = union(enum) {
// These are strange: we'll sometimes represent them as f128, even if the
// underlying type is smaller. f80 is an exception: see float_c_longdouble_f80.
const a_val = switch (a_info.storage) {
- inline else => |val| @as(f128, @floatCast(val)),
+ inline else => |val| @as(u128, @bitCast(@as(f128, @floatCast(val)))),
};
const b_val = switch (b_info.storage) {
- inline else => |val| @as(f128, @floatCast(val)),
+ inline else => |val| @as(u128, @bitCast(@as(f128, @floatCast(val)))),
};
return a_val == b_val;
}
@@ -1567,9 +1567,14 @@ pub const Key = union(enum) {
const StorageTag = @typeInfo(Key.Float.Storage).Union.tag_type.?;
assert(@as(StorageTag, a_info.storage) == @as(StorageTag, b_info.storage));
- return switch (a_info.storage) {
- inline else => |val, tag| val == @field(b_info.storage, @tagName(tag)),
- };
+ switch (a_info.storage) {
+ inline else => |val, tag| {
+ const Bits = std.meta.Int(.unsigned, @bitSizeOf(@TypeOf(val)));
+ const a_bits: Bits = @bitCast(val);
+ const b_bits: Bits = @bitCast(@field(b_info.storage, @tagName(tag)));
+ return a_bits == b_bits;
+ },
+ }
},
.opaque_type => |a_info| {