authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-11-10 17:55:16+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-11-10 17:21:49-05:00
log4d4ab1e69a40fb11d19e93b42a02016f9d009aef
treeca4312aad89b1a198eab033f972ee2882d8ce04b
parent06a3a69e6f38798b1768976520b8db40c9a210bf

stage1: Fix comparison of unions containing zero-sized types

The code tried to be too smart and skipped the equality (returning true) if the payload type was zero-sized. This optimization is completely wrong when the union payload is a metatype! Fixes #7047

3 files changed, 23 insertions(+), 2 deletions(-)

src/stage1/analyze.cpp-2
......@@ -7079,8 +7079,6 @@ bool const_values_equal(CodeGen *g, ZigValue *a, ZigValue *b) {
70797079 if (bigint_cmp(&union1->tag, &union2->tag) == CmpEQ) {
70807080 TypeUnionField *field = find_union_field_by_tag(a->type, &union1->tag);
70817081 assert(field != nullptr);
7082 if (!type_has_bits(g, field->type_entry))
7083 return true;
70847082 assert(find_union_field_by_tag(a->type, &union2->tag) != nullptr);
70857083 return const_values_equal(g, union1->payload, union2->payload);
70867084 }
test/stage1/behavior.zig+1
......@@ -56,6 +56,7 @@ comptime {
5656 _ = @import("behavior/bugs/6456.zig");
5757 _ = @import("behavior/bugs/6781.zig");
5858 _ = @import("behavior/bugs/6850.zig");
59 _ = @import("behavior/bugs/7047.zig");
5960 _ = @import("behavior/bugs/394.zig");
6061 _ = @import("behavior/bugs/421.zig");
6162 _ = @import("behavior/bugs/529.zig");
test/stage1/behavior/bugs/7047.zig created+22
......@@ -0,0 +1,22 @@
1const std = @import("std");
2
3const U = union(enum) {
4 T: type,
5 N: void,
6};
7
8fn S(comptime query: U) type {
9 return struct {
10 fn tag() type {
11 return query.T;
12 }
13 };
14}
15
16test "compiler doesn't consider equal unions with different 'type' payload" {
17 const s1 = S(U{ .T = u32 }).tag();
18 std.testing.expectEqual(u32, s1);
19
20 const s2 = S(U{ .T = u64 }).tag();
21 std.testing.expectEqual(u64, s2);
22}