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 **...@@ -1432,8 +1432,8 @@ static bool analyze_const_string(CodeGen *g, Scope *scope, AstNode *node, Buf **
1432 return true;1432 return true;
1433}1433}
14341434
1435static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType *type_entry,1435static Error emit_error_unless_type_allowed_in_packed_container(CodeGen *g, ZigType *type_entry,
1436 AstNode *source_node)1436 AstNode *source_node, const char* container_name)
1437{1437{
1438 Error err;1438 Error err;
1439 switch (type_entry->id) {1439 switch (type_entry->id) {
...@@ -1454,8 +1454,8 @@ static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType...@@ -1454,8 +1454,8 @@ static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType
1454 case ZigTypeIdFnFrame:1454 case ZigTypeIdFnFrame:
1455 case ZigTypeIdAnyFrame:1455 case ZigTypeIdAnyFrame:
1456 add_node_error(g, source_node,1456 add_node_error(g, source_node,
1457 buf_sprintf("type '%s' not allowed in packed struct; no guaranteed in-memory representation",1457 buf_sprintf("type '%s' not allowed in packed %s; no guaranteed in-memory representation",
1458 buf_ptr(&type_entry->name)));1458 buf_ptr(&type_entry->name), container_name));
1459 return ErrorSemanticAnalyzeFail;1459 return ErrorSemanticAnalyzeFail;
1460 case ZigTypeIdVoid:1460 case ZigTypeIdVoid:
1461 case ZigTypeIdBool:1461 case ZigTypeIdBool:
...@@ -1467,14 +1467,14 @@ static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType...@@ -1467,14 +1467,14 @@ static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType
1467 return ErrorNone;1467 return ErrorNone;
1468 case ZigTypeIdArray: {1468 case ZigTypeIdArray: {
1469 ZigType *elem_type = type_entry->data.array.child_type;1469 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)))
1471 return err;1471 return err;
1472 // TODO revisit this when doing https://github.com/ziglang/zig/issues/15121472 // TODO revisit this when doing https://github.com/ziglang/zig/issues/1512
1473 if (type_size(g, type_entry) * 8 == type_size_bits(g, type_entry))1473 if (type_size(g, type_entry) * 8 == type_size_bits(g, type_entry))
1474 return ErrorNone;1474 return ErrorNone;
1475 add_node_error(g, source_node,1475 add_node_error(g, source_node,
1476 buf_sprintf("array of '%s' not allowed in packed struct due to padding bits",1476 buf_sprintf("array of '%s' not allowed in packed %s due to padding bits",
1477 buf_ptr(&elem_type->name)));1477 buf_ptr(&elem_type->name), container_name));
1478 return ErrorSemanticAnalyzeFail;1478 return ErrorSemanticAnalyzeFail;
1479 }1479 }
1480 case ZigTypeIdStruct:1480 case ZigTypeIdStruct:
...@@ -1484,8 +1484,8 @@ static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType...@@ -1484,8 +1484,8 @@ static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType
1484 return ErrorNone;1484 return ErrorNone;
1485 case ContainerLayoutAuto:1485 case ContainerLayoutAuto:
1486 add_node_error(g, source_node,1486 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",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)));1488 buf_ptr(&type_entry->name), container_name));
1489 return ErrorSemanticAnalyzeFail;1489 return ErrorSemanticAnalyzeFail;
1490 }1490 }
1491 zig_unreachable();1491 zig_unreachable();
...@@ -1496,8 +1496,8 @@ static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType...@@ -1496,8 +1496,8 @@ static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType
1496 return ErrorNone;1496 return ErrorNone;
1497 case ContainerLayoutAuto:1497 case ContainerLayoutAuto:
1498 add_node_error(g, source_node,1498 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",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)));1500 buf_ptr(&type_entry->name), container_name));
1501 return ErrorSemanticAnalyzeFail;1501 return ErrorSemanticAnalyzeFail;
1502 }1502 }
1503 zig_unreachable();1503 zig_unreachable();
...@@ -1506,8 +1506,8 @@ static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType...@@ -1506,8 +1506,8 @@ static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType
1506 return ErrorNone;1506 return ErrorNone;
1507 } else {1507 } else {
1508 add_node_error(g, source_node,1508 add_node_error(g, source_node,
1509 buf_sprintf("type '%s' not allowed in packed struct; no guaranteed in-memory representation",1509 buf_sprintf("type '%s' not allowed in packed %s; no guaranteed in-memory representation",
1510 buf_ptr(&type_entry->name)));1510 buf_ptr(&type_entry->name), container_name));
1511 return ErrorSemanticAnalyzeFail;1511 return ErrorSemanticAnalyzeFail;
1512 }1512 }
1513 case ZigTypeIdEnum: {1513 case ZigTypeIdEnum: {
...@@ -1516,8 +1516,8 @@ static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType...@@ -1516,8 +1516,8 @@ static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType
1516 return ErrorNone;1516 return ErrorNone;
1517 }1517 }
1518 ErrorMsg *msg = add_node_error(g, source_node,1518 ErrorMsg *msg = add_node_error(g, source_node,
1519 buf_sprintf("type '%s' not allowed in packed struct; no guaranteed in-memory representation",1519 buf_sprintf("type '%s' not allowed in packed %s; no guaranteed in-memory representation",
1520 buf_ptr(&type_entry->name)));1520 buf_ptr(&type_entry->name), container_name));
1521 add_error_note(g, msg, decl_node,1521 add_error_note(g, msg, decl_node,
1522 buf_sprintf("enum declaration does not specify an integer tag type"));1522 buf_sprintf("enum declaration does not specify an integer tag type"));
1523 return ErrorSemanticAnalyzeFail;1523 return ErrorSemanticAnalyzeFail;
...@@ -1526,6 +1526,18 @@ static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType...@@ -1526,6 +1526,18 @@ static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType
1526 zig_unreachable();1526 zig_unreachable();
1527}1527}
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
1529bool type_allowed_in_extern(CodeGen *g, ZigType *type_entry) {1541bool type_allowed_in_extern(CodeGen *g, ZigType *type_entry) {
1530 switch (type_entry->id) {1542 switch (type_entry->id) {
1531 case ZigTypeIdInvalid:1543 case ZigTypeIdInvalid:
...@@ -2286,6 +2298,8 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) {...@@ -2286,6 +2298,8 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) {
2286 // set temporary flag2298 // set temporary flag
2287 union_type->data.unionation.resolve_loop_flag_other = true;2299 union_type->data.unionation.resolve_loop_flag_other = true;
22882300
2301 const bool is_packed = union_type->data.unionation.layout == ContainerLayoutPacked;
2302
2289 for (uint32_t i = 0; i < field_count; i += 1) {2303 for (uint32_t i = 0; i < field_count; i += 1) {
2290 TypeUnionField *union_field = &union_type->data.unionation.fields[i];2304 TypeUnionField *union_field = &union_type->data.unionation.fields[i];
2291 ZigType *field_type = resolve_union_field_type(g, union_field);2305 ZigType *field_type = resolve_union_field_type(g, union_field);
...@@ -2298,6 +2312,12 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) {...@@ -2298,6 +2312,12 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) {
2298 union_type->data.unionation.resolve_status = ResolveStatusInvalid;2312 union_type->data.unionation.resolve_status = ResolveStatusInvalid;
2299 return ErrorSemanticAnalyzeFail;2313 return ErrorSemanticAnalyzeFail;
2300 }2314 }
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
2302 if (type_is_invalid(union_type))2322 if (type_is_invalid(union_type))
2303 return ErrorSemanticAnalyzeFail;2323 return ErrorSemanticAnalyzeFail;
test/compile_errors.zig+17
...@@ -6308,6 +6308,23 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6308,6 +6308,23 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6308 "tmp.zig:6:30: error: packed union does not support enum tag type",6308 "tmp.zig:6:30: error: packed union does not support enum tag type",
6309 );6309 );
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
6311 cases.add(6328 cases.add(
6312 "switch on union with no attached enum",6329 "switch on union with no attached enum",
6313 \\const Payload = union {6330 \\const Payload = union {