mirror of
https://github.com/ziglang/zig.git
synced 2026-02-16 06:18:32 +00:00
reject types of automatic container layout in packed unions
This commit is contained in:
parent
c9a5a6b83a
commit
74d0b5bf7c
@ -1432,8 +1432,8 @@ static bool analyze_const_string(CodeGen *g, Scope *scope, AstNode *node, Buf **
|
||||
return true;
|
||||
}
|
||||
|
||||
static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType *type_entry,
|
||||
AstNode *source_node)
|
||||
static Error emit_error_unless_type_allowed_in_packed_container(CodeGen *g, ZigType *type_entry,
|
||||
AstNode *source_node, const char* container_name)
|
||||
{
|
||||
Error err;
|
||||
switch (type_entry->id) {
|
||||
@ -1454,8 +1454,8 @@ static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType
|
||||
case ZigTypeIdFnFrame:
|
||||
case ZigTypeIdAnyFrame:
|
||||
add_node_error(g, source_node,
|
||||
buf_sprintf("type '%s' not allowed in packed struct; no guaranteed in-memory representation",
|
||||
buf_ptr(&type_entry->name)));
|
||||
buf_sprintf("type '%s' not allowed in packed %s; no guaranteed in-memory representation",
|
||||
buf_ptr(&type_entry->name), container_name));
|
||||
return ErrorSemanticAnalyzeFail;
|
||||
case ZigTypeIdVoid:
|
||||
case ZigTypeIdBool:
|
||||
@ -1467,14 +1467,14 @@ static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType
|
||||
return ErrorNone;
|
||||
case ZigTypeIdArray: {
|
||||
ZigType *elem_type = type_entry->data.array.child_type;
|
||||
if ((err = emit_error_unless_type_allowed_in_packed_struct(g, elem_type, source_node)))
|
||||
if ((err = emit_error_unless_type_allowed_in_packed_container(g, elem_type, source_node, container_name)))
|
||||
return err;
|
||||
// TODO revisit this when doing https://github.com/ziglang/zig/issues/1512
|
||||
if (type_size(g, type_entry) * 8 == type_size_bits(g, type_entry))
|
||||
return ErrorNone;
|
||||
add_node_error(g, source_node,
|
||||
buf_sprintf("array of '%s' not allowed in packed struct due to padding bits",
|
||||
buf_ptr(&elem_type->name)));
|
||||
buf_sprintf("array of '%s' not allowed in packed %s due to padding bits",
|
||||
buf_ptr(&elem_type->name), container_name));
|
||||
return ErrorSemanticAnalyzeFail;
|
||||
}
|
||||
case ZigTypeIdStruct:
|
||||
@ -1484,8 +1484,8 @@ static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType
|
||||
return ErrorNone;
|
||||
case ContainerLayoutAuto:
|
||||
add_node_error(g, source_node,
|
||||
buf_sprintf("non-packed, non-extern struct '%s' not allowed in packed struct; no guaranteed in-memory representation",
|
||||
buf_ptr(&type_entry->name)));
|
||||
buf_sprintf("non-packed, non-extern struct '%s' not allowed in packed %s; no guaranteed in-memory representation",
|
||||
buf_ptr(&type_entry->name), container_name));
|
||||
return ErrorSemanticAnalyzeFail;
|
||||
}
|
||||
zig_unreachable();
|
||||
@ -1496,8 +1496,8 @@ static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType
|
||||
return ErrorNone;
|
||||
case ContainerLayoutAuto:
|
||||
add_node_error(g, source_node,
|
||||
buf_sprintf("non-packed, non-extern union '%s' not allowed in packed struct; no guaranteed in-memory representation",
|
||||
buf_ptr(&type_entry->name)));
|
||||
buf_sprintf("non-packed, non-extern union '%s' not allowed in packed %s; no guaranteed in-memory representation",
|
||||
buf_ptr(&type_entry->name), container_name));
|
||||
return ErrorSemanticAnalyzeFail;
|
||||
}
|
||||
zig_unreachable();
|
||||
@ -1506,8 +1506,8 @@ static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType
|
||||
return ErrorNone;
|
||||
} else {
|
||||
add_node_error(g, source_node,
|
||||
buf_sprintf("type '%s' not allowed in packed struct; no guaranteed in-memory representation",
|
||||
buf_ptr(&type_entry->name)));
|
||||
buf_sprintf("type '%s' not allowed in packed %s; no guaranteed in-memory representation",
|
||||
buf_ptr(&type_entry->name), container_name));
|
||||
return ErrorSemanticAnalyzeFail;
|
||||
}
|
||||
case ZigTypeIdEnum: {
|
||||
@ -1516,8 +1516,8 @@ static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType
|
||||
return ErrorNone;
|
||||
}
|
||||
ErrorMsg *msg = add_node_error(g, source_node,
|
||||
buf_sprintf("type '%s' not allowed in packed struct; no guaranteed in-memory representation",
|
||||
buf_ptr(&type_entry->name)));
|
||||
buf_sprintf("type '%s' not allowed in packed %s; no guaranteed in-memory representation",
|
||||
buf_ptr(&type_entry->name), container_name));
|
||||
add_error_note(g, msg, decl_node,
|
||||
buf_sprintf("enum declaration does not specify an integer tag type"));
|
||||
return ErrorSemanticAnalyzeFail;
|
||||
@ -1526,6 +1526,18 @@ static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType
|
||||
zig_unreachable();
|
||||
}
|
||||
|
||||
static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType *type_entry,
|
||||
AstNode *source_node)
|
||||
{
|
||||
return emit_error_unless_type_allowed_in_packed_container(g, type_entry, source_node, "struct");
|
||||
}
|
||||
|
||||
static Error emit_error_unless_type_allowed_in_packed_union(CodeGen *g, ZigType *type_entry,
|
||||
AstNode *source_node)
|
||||
{
|
||||
return emit_error_unless_type_allowed_in_packed_container(g, type_entry, source_node, "union");
|
||||
}
|
||||
|
||||
bool type_allowed_in_extern(CodeGen *g, ZigType *type_entry) {
|
||||
switch (type_entry->id) {
|
||||
case ZigTypeIdInvalid:
|
||||
@ -2286,6 +2298,8 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) {
|
||||
// set temporary flag
|
||||
union_type->data.unionation.resolve_loop_flag_other = true;
|
||||
|
||||
const bool is_packed = union_type->data.unionation.layout == ContainerLayoutPacked;
|
||||
|
||||
for (uint32_t i = 0; i < field_count; i += 1) {
|
||||
TypeUnionField *union_field = &union_type->data.unionation.fields[i];
|
||||
ZigType *field_type = resolve_union_field_type(g, union_field);
|
||||
@ -2298,6 +2312,12 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) {
|
||||
union_type->data.unionation.resolve_status = ResolveStatusInvalid;
|
||||
return ErrorSemanticAnalyzeFail;
|
||||
}
|
||||
if (is_packed) {
|
||||
if ((err = emit_error_unless_type_allowed_in_packed_union(g, field_type, union_field->decl_node))) {
|
||||
union_type->data.unionation.resolve_status = ResolveStatusInvalid;
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
if (type_is_invalid(union_type))
|
||||
return ErrorSemanticAnalyzeFail;
|
||||
|
||||
@ -6308,6 +6308,23 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
"tmp.zig:6:30: error: packed union does not support enum tag type",
|
||||
);
|
||||
|
||||
cases.add(
|
||||
"packed union with automatic layout field",
|
||||
\\const Foo = struct {
|
||||
\\ a: u32,
|
||||
\\ b: f32,
|
||||
\\};
|
||||
\\const Payload = packed union {
|
||||
\\ A: Foo,
|
||||
\\ B: bool,
|
||||
\\};
|
||||
\\export fn entry() void {
|
||||
\\ var a = Payload { .B = true };
|
||||
\\}
|
||||
,
|
||||
"tmp.zig:6:5: error: non-packed, non-extern struct 'Foo' not allowed in packed union; no guaranteed in-memory representation",
|
||||
);
|
||||
|
||||
cases.add(
|
||||
"switch on union with no attached enum",
|
||||
\\const Payload = union {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user