Sema: disallow tags on non-auto unions when reifying (#23488)
This commit is contained in:
committed by
GitHub
parent
cf7a28febb
commit
3d639481d9
10
src/Sema.zig
10
src/Sema.zig
@@ -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);
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user