authorgravatar for sahnvour@pm.meSahnvour <sahnvour@pm.me> 2019-09-01 12:46:02+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-09-20 13:25:32-04:00
log74d0b5bf7c5bdb5013cec7d6eb6b474fe1ad703a
treeb2ad0cba9959add8c9d082d0f95246847693bc55
parentc9a5a6b83abaeef232ce3f0d2407c59f8769e9e5

reject types of automatic container layout in packed unions


2 files changed, 52 insertions(+), 15 deletions(-)

src/analyze.cpp+35-15
......@@ -1432,8 +1432,8 @@ static bool analyze_const_string(CodeGen *g, Scope *scope, AstNode *node, Buf **
14321432 return true;
14331433}
14341434
1435static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType *type_entry,
1436 AstNode *source_node)
1435static Error emit_error_unless_type_allowed_in_packed_container(CodeGen *g, ZigType *type_entry,
1436 AstNode *source_node, const char* container_name)
14371437{
14381438 Error err;
14391439 switch (type_entry->id) {
......@@ -1454,8 +1454,8 @@ static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType
14541454 case ZigTypeIdFnFrame:
14551455 case ZigTypeIdAnyFrame:
14561456 add_node_error(g, source_node,
1457 buf_sprintf("type '%s' not allowed in packed struct; no guaranteed in-memory representation",
1458 buf_ptr(&type_entry->name)));
1457 buf_sprintf("type '%s' not allowed in packed %s; no guaranteed in-memory representation",
1458 buf_ptr(&type_entry->name), container_name));
14591459 return ErrorSemanticAnalyzeFail;
14601460 case ZigTypeIdVoid:
14611461 case ZigTypeIdBool:
......@@ -1467,14 +1467,14 @@ static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType
14671467 return ErrorNone;
14681468 case ZigTypeIdArray: {
14691469 ZigType *elem_type = type_entry->data.array.child_type;
1470 if ((err = emit_error_unless_type_allowed_in_packed_struct(g, elem_type, source_node)))
1470 if ((err = emit_error_unless_type_allowed_in_packed_container(g, elem_type, source_node, container_name)))
14711471 return err;
14721472 // TODO revisit this when doing https://github.com/ziglang/zig/issues/1512
14731473 if (type_size(g, type_entry) * 8 == type_size_bits(g, type_entry))
14741474 return ErrorNone;
14751475 add_node_error(g, source_node,
1476 buf_sprintf("array of '%s' not allowed in packed struct due to padding bits",
1477 buf_ptr(&elem_type->name)));
1476 buf_sprintf("array of '%s' not allowed in packed %s due to padding bits",
1477 buf_ptr(&elem_type->name), container_name));
14781478 return ErrorSemanticAnalyzeFail;
14791479 }
14801480 case ZigTypeIdStruct:
......@@ -1484,8 +1484,8 @@ static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType
14841484 return ErrorNone;
14851485 case ContainerLayoutAuto:
14861486 add_node_error(g, source_node,
1487 buf_sprintf("non-packed, non-extern struct '%s' not allowed in packed struct; no guaranteed in-memory representation",
1488 buf_ptr(&type_entry->name)));
1487 buf_sprintf("non-packed, non-extern struct '%s' not allowed in packed %s; no guaranteed in-memory representation",
1488 buf_ptr(&type_entry->name), container_name));
14891489 return ErrorSemanticAnalyzeFail;
14901490 }
14911491 zig_unreachable();
......@@ -1496,8 +1496,8 @@ static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType
14961496 return ErrorNone;
14971497 case ContainerLayoutAuto:
14981498 add_node_error(g, source_node,
1499 buf_sprintf("non-packed, non-extern union '%s' not allowed in packed struct; no guaranteed in-memory representation",
1500 buf_ptr(&type_entry->name)));
1499 buf_sprintf("non-packed, non-extern union '%s' not allowed in packed %s; no guaranteed in-memory representation",
1500 buf_ptr(&type_entry->name), container_name));
15011501 return ErrorSemanticAnalyzeFail;
15021502 }
15031503 zig_unreachable();
......@@ -1506,8 +1506,8 @@ static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType
15061506 return ErrorNone;
15071507 } else {
15081508 add_node_error(g, source_node,
1509 buf_sprintf("type '%s' not allowed in packed struct; no guaranteed in-memory representation",
1510 buf_ptr(&type_entry->name)));
1509 buf_sprintf("type '%s' not allowed in packed %s; no guaranteed in-memory representation",
1510 buf_ptr(&type_entry->name), container_name));
15111511 return ErrorSemanticAnalyzeFail;
15121512 }
15131513 case ZigTypeIdEnum: {
......@@ -1516,8 +1516,8 @@ static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType
15161516 return ErrorNone;
15171517 }
15181518 ErrorMsg *msg = add_node_error(g, source_node,
1519 buf_sprintf("type '%s' not allowed in packed struct; no guaranteed in-memory representation",
1520 buf_ptr(&type_entry->name)));
1519 buf_sprintf("type '%s' not allowed in packed %s; no guaranteed in-memory representation",
1520 buf_ptr(&type_entry->name), container_name));
15211521 add_error_note(g, msg, decl_node,
15221522 buf_sprintf("enum declaration does not specify an integer tag type"));
15231523 return ErrorSemanticAnalyzeFail;
......@@ -1526,6 +1526,18 @@ static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType
15261526 zig_unreachable();
15271527}
15281528
1529static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType *type_entry,
1530 AstNode *source_node)
1531{
1532 return emit_error_unless_type_allowed_in_packed_container(g, type_entry, source_node, "struct");
1533}
1534
1535static Error emit_error_unless_type_allowed_in_packed_union(CodeGen *g, ZigType *type_entry,
1536 AstNode *source_node)
1537{
1538 return emit_error_unless_type_allowed_in_packed_container(g, type_entry, source_node, "union");
1539}
1540
15291541bool type_allowed_in_extern(CodeGen *g, ZigType *type_entry) {
15301542 switch (type_entry->id) {
15311543 case ZigTypeIdInvalid:
......@@ -2286,6 +2298,8 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) {
22862298 // set temporary flag
22872299 union_type->data.unionation.resolve_loop_flag_other = true;
22882300
2301 const bool is_packed = union_type->data.unionation.layout == ContainerLayoutPacked;
2302
22892303 for (uint32_t i = 0; i < field_count; i += 1) {
22902304 TypeUnionField *union_field = &union_type->data.unionation.fields[i];
22912305 ZigType *field_type = resolve_union_field_type(g, union_field);
......@@ -2298,6 +2312,12 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) {
22982312 union_type->data.unionation.resolve_status = ResolveStatusInvalid;
22992313 return ErrorSemanticAnalyzeFail;
23002314 }
2315 if (is_packed) {
2316 if ((err = emit_error_unless_type_allowed_in_packed_union(g, field_type, union_field->decl_node))) {
2317 union_type->data.unionation.resolve_status = ResolveStatusInvalid;
2318 return err;
2319 }
2320 }
23012321
23022322 if (type_is_invalid(union_type))
23032323 return ErrorSemanticAnalyzeFail;
test/compile_errors.zig+17
......@@ -6308,6 +6308,23 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
63086308 "tmp.zig:6:30: error: packed union does not support enum tag type",
63096309 );
63106310
6311 cases.add(
6312 "packed union with automatic layout field",
6313 \\const Foo = struct {
6314 \\ a: u32,
6315 \\ b: f32,
6316 \\};
6317 \\const Payload = packed union {
6318 \\ A: Foo,
6319 \\ B: bool,
6320 \\};
6321 \\export fn entry() void {
6322 \\ var a = Payload { .B = true };
6323 \\}
6324 ,
6325 "tmp.zig:6:5: error: non-packed, non-extern struct 'Foo' not allowed in packed union; no guaranteed in-memory representation",
6326 );
6327
63116328 cases.add(
63126329 "switch on union with no attached enum",
63136330 \\const Payload = union {