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

This commit is contained in:
Krzysztof Wolicki
2025-07-30 20:18:49 +02:00
committed by GitHub
parent cf7a28febb
commit 3d639481d9
3 changed files with 78 additions and 0 deletions

View File

@@ -20630,6 +20630,16 @@ fn zirReify(
}
const layout = try sema.interpretBuiltinType(block, operand_src, layout_val, std.builtin.Type.ContainerLayout);
const has_tag = tag_type_val.optionalValue(zcu) != null;
if (has_tag) {
switch (layout) {
.@"extern" => return sema.fail(block, src, "extern union does not support enum tag type", .{}),
.@"packed" => return sema.fail(block, src, "packed union does not support enum tag type", .{}),
.auto => {},
}
}
const fields_arr = try sema.derefSliceAsArray(block, operand_src, fields_val, .{ .simple = .union_fields });
return sema.reifyUnion(block, inst, src, layout, tag_type_val, fields_arr, name_strategy);

View File

@@ -0,0 +1,34 @@
const Tag = @Type(.{
.@"enum" = .{
.tag_type = u2,
.fields = &.{
.{ .name = "signed", .value = 0 },
.{ .name = "unsigned", .value = 1 },
},
.decls = &.{},
.is_exhaustive = true,
},
});
const Extern = @Type(.{
.@"union" = .{
.layout = .@"extern",
.tag_type = Tag,
.fields = &.{
.{ .name = "signed", .type = i32, .alignment = @alignOf(i32) },
.{ .name = "unsigned", .type = u32, .alignment = @alignOf(u32) },
},
.decls = &.{},
},
});
export fn entry() void {
const tagged: Extern = .{ .signed = -1 };
_ = tagged;
}
// error
// backend=stage2
// target=native
//
// :13:16: error: extern union does not support enum tag type

View File

@@ -0,0 +1,34 @@
const Tag = @Type(.{
.@"enum" = .{
.tag_type = u2,
.fields = &.{
.{ .name = "signed", .value = 0 },
.{ .name = "unsigned", .value = 1 },
},
.decls = &.{},
.is_exhaustive = true,
},
});
const Packed = @Type(.{
.@"union" = .{
.layout = .@"packed",
.tag_type = Tag,
.fields = &.{
.{ .name = "signed", .type = i32, .alignment = @alignOf(i32) },
.{ .name = "unsigned", .type = u32, .alignment = @alignOf(u32) },
},
.decls = &.{},
},
});
export fn entry() void {
const tagged: Packed = .{ .signed = -1 };
_ = tagged;
}
// error
// backend=stage2
// target=native
//
// :13:16: error: packed union does not support enum tag type