authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2019-09-01 19:47:58+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-09-05 13:07:04-04:00
log8e3c56b912b7eb6ee551b7e427adbaae0bdcd408
tree9ecd46b466947437e23e4d759713d9dab4161cd9
parent0107b19124255179a48cd605f31ed57d5ade28e7
signaturelock-open Commit is signed but in an unrecognized format.

Always resolve the struct field types

Packed structs used to skip the zero-sized types and trip some assertions that expected the type reference not to be null. Fixes #3143

2 files changed, 27 insertions(+), 23 deletions(-)

src/analyze.cpp+19-23
......@@ -2043,34 +2043,30 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {
20432043
20442044
20452045 // Resolve types for fields
2046 if (!packed) {
2047 for (size_t i = 0; i < field_count; i += 1) {
2048 TypeStructField *field = &struct_type->data.structure.fields[i];
2049 ZigType *field_type = resolve_struct_field_type(g, field);
2050 if (field_type == nullptr) {
2051 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2052 return err;
2053 }
2054
2055 if ((err = type_resolve(g, field_type, ResolveStatusSizeKnown))) {
2056 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2057 return err;
2058 }
2046 for (size_t i = 0; i < field_count; i += 1) {
2047 TypeStructField *field = &struct_type->data.structure.fields[i];
2048 ZigType *field_type = resolve_struct_field_type(g, field);
2049 if (field_type == nullptr) {
2050 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2051 return err;
2052 }
20592053
2060 if (struct_type->data.structure.layout == ContainerLayoutExtern &&
2061 !type_allowed_in_extern(g, field_type))
2062 {
2063 add_node_error(g, field->decl_node,
2064 buf_sprintf("extern structs cannot contain fields of type '%s'",
2065 buf_ptr(&field_type->name)));
2066 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2067 return ErrorSemanticAnalyzeFail;
2068 }
2054 if ((err = type_resolve(g, field_type, ResolveStatusSizeKnown))) {
2055 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2056 return err;
2057 }
20692058
2059 if (struct_type->data.structure.layout == ContainerLayoutExtern &&
2060 !type_allowed_in_extern(g, field_type))
2061 {
2062 add_node_error(g, field->decl_node,
2063 buf_sprintf("extern structs cannot contain fields of type '%s'",
2064 buf_ptr(&field_type->name)));
2065 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2066 return ErrorSemanticAnalyzeFail;
20702067 }
20712068 }
20722069
2073
20742070 return ErrorNone;
20752071}
20762072
test/stage1/behavior/struct.zig+8
......@@ -632,3 +632,11 @@ test "for loop over pointers to struct, getting field from struct pointer" {
632632 };
633633 S.doTheTest();
634634}
635
636test "zero-bit field in packed struct" {
637 const S = packed struct {
638 x: u10,
639 y: void,
640 };
641 var x: S = undefined;
642}