authorgravatar for der.teufel.mail@gmail.comKrzysztof Wolicki <der.teufel.mail@gmail.com> 2025-07-30 20:18:49+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2025-07-30 18:18:49+00:00
log3d639481d9001df391744720b756b7f97dce2c01
treebcb5fb9a98314ff95369def839afea8aed91451b
parentcf7a28febbbe877003d8d4f9a13ceb94698c1e3e
signaturebadge-check Signed by PGP key B5690EEEBB952194

Sema: disallow tags on non-auto unions when reifying (#23488)


3 files changed, 78 insertions(+), 0 deletions(-)

src/Sema.zig+10
...@@ -20630,6 +20630,16 @@ fn zirReify(...@@ -20630,6 +20630,16 @@ fn zirReify(
20630 }20630 }
20631 const layout = try sema.interpretBuiltinType(block, operand_src, layout_val, std.builtin.Type.ContainerLayout);20631 const layout = try sema.interpretBuiltinType(block, operand_src, layout_val, std.builtin.Type.ContainerLayout);
2063220632
20633 const has_tag = tag_type_val.optionalValue(zcu) != null;
20634
20635 if (has_tag) {
20636 switch (layout) {
20637 .@"extern" => return sema.fail(block, src, "extern union does not support enum tag type", .{}),
20638 .@"packed" => return sema.fail(block, src, "packed union does not support enum tag type", .{}),
20639 .auto => {},
20640 }
20641 }
20642
20633 const fields_arr = try sema.derefSliceAsArray(block, operand_src, fields_val, .{ .simple = .union_fields });20643 const fields_arr = try sema.derefSliceAsArray(block, operand_src, fields_val, .{ .simple = .union_fields });
2063420644
20635 return sema.reifyUnion(block, inst, src, layout, tag_type_val, fields_arr, name_strategy);20645 return sema.reifyUnion(block, inst, src, layout, tag_type_val, fields_arr, name_strategy);
test/cases/compile_errors/reify_type_for_tagged_extern_union.zig created+34
...@@ -0,0 +1,34 @@
1const Tag = @Type(.{
2 .@"enum" = .{
3 .tag_type = u2,
4 .fields = &.{
5 .{ .name = "signed", .value = 0 },
6 .{ .name = "unsigned", .value = 1 },
7 },
8 .decls = &.{},
9 .is_exhaustive = true,
10 },
11});
12
13const Extern = @Type(.{
14 .@"union" = .{
15 .layout = .@"extern",
16 .tag_type = Tag,
17 .fields = &.{
18 .{ .name = "signed", .type = i32, .alignment = @alignOf(i32) },
19 .{ .name = "unsigned", .type = u32, .alignment = @alignOf(u32) },
20 },
21 .decls = &.{},
22 },
23});
24
25export fn entry() void {
26 const tagged: Extern = .{ .signed = -1 };
27 _ = tagged;
28}
29
30// error
31// backend=stage2
32// target=native
33//
34// :13:16: error: extern union does not support enum tag type
test/cases/compile_errors/reify_type_for_tagged_packed_union.zig created+34
...@@ -0,0 +1,34 @@
1const Tag = @Type(.{
2 .@"enum" = .{
3 .tag_type = u2,
4 .fields = &.{
5 .{ .name = "signed", .value = 0 },
6 .{ .name = "unsigned", .value = 1 },
7 },
8 .decls = &.{},
9 .is_exhaustive = true,
10 },
11});
12
13const Packed = @Type(.{
14 .@"union" = .{
15 .layout = .@"packed",
16 .tag_type = Tag,
17 .fields = &.{
18 .{ .name = "signed", .type = i32, .alignment = @alignOf(i32) },
19 .{ .name = "unsigned", .type = u32, .alignment = @alignOf(u32) },
20 },
21 .decls = &.{},
22 },
23});
24
25export fn entry() void {
26 const tagged: Packed = .{ .signed = -1 };
27 _ = tagged;
28}
29
30// error
31// backend=stage2
32// target=native
33//
34// :13:16: error: packed union does not support enum tag type