| ... | @@ -2038,6 +2038,8 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { | ... | @@ -2038,6 +2038,8 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { |
| 2038 | static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) { | 2038 | static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) { |
| 2039 | assert(struct_type->id == ZigTypeIdStruct); | 2039 | assert(struct_type->id == ZigTypeIdStruct); |
| 2040 | | 2040 | |
| | 2041 | Error err; |
| | 2042 | |
| 2041 | if (struct_type->data.structure.resolve_status == ResolveStatusInvalid) | 2043 | if (struct_type->data.structure.resolve_status == ResolveStatusInvalid) |
| 2042 | return ErrorSemanticAnalyzeFail; | 2044 | return ErrorSemanticAnalyzeFail; |
| 2043 | if (struct_type->data.structure.resolve_status >= ResolveStatusZeroBitsKnown) | 2045 | if (struct_type->data.structure.resolve_status >= ResolveStatusZeroBitsKnown) |
| ... | @@ -2047,13 +2049,12 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) { | ... | @@ -2047,13 +2049,12 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) { |
| 2047 | assert(decl_node->type == NodeTypeContainerDecl); | 2049 | assert(decl_node->type == NodeTypeContainerDecl); |
| 2048 | | 2050 | |
| 2049 | if (struct_type->data.structure.resolve_loop_flag) { | 2051 | if (struct_type->data.structure.resolve_loop_flag) { |
| 2050 | if (struct_type->data.structure.resolve_status != ResolveStatusInvalid) { | 2052 | // TODO This is a problem. I believe it can be solved with lazy values. |
| 2051 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; | 2053 | struct_type->size_in_bits = SIZE_MAX;; |
| 2052 | ErrorMsg *msg = add_node_error(g, decl_node, | 2054 | struct_type->abi_size = SIZE_MAX;; |
| 2053 | buf_sprintf("struct '%s' depends on its own size", buf_ptr(&struct_type->name))); | 2055 | struct_type->data.structure.resolve_status = ResolveStatusZeroBitsKnown; |
| 2054 | emit_error_notes_for_ref_stack(g, msg); | 2056 | struct_type->data.structure.resolve_loop_flag = false; |
| 2055 | } | 2057 | return ErrorNone; |
| 2056 | return ErrorSemanticAnalyzeFail; | | |
| 2057 | } | 2058 | } |
| 2058 | | 2059 | |
| 2059 | struct_type->data.structure.resolve_loop_flag = true; | 2060 | struct_type->data.structure.resolve_loop_flag = true; |
| ... | @@ -2097,6 +2098,21 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) { | ... | @@ -2097,6 +2098,21 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) { |
| 2097 | if (struct_type->data.structure.resolve_status == ResolveStatusInvalid) | 2098 | if (struct_type->data.structure.resolve_status == ResolveStatusInvalid) |
| 2098 | return ErrorSemanticAnalyzeFail; | 2099 | return ErrorSemanticAnalyzeFail; |
| 2099 | | 2100 | |
| | 2101 | if (struct_type->data.structure.layout == ContainerLayoutExtern && |
| | 2102 | !type_allowed_in_extern(g, field_type)) |
| | 2103 | { |
| | 2104 | add_node_error(g, field_node, |
| | 2105 | buf_sprintf("extern structs cannot contain fields of type '%s'", |
| | 2106 | buf_ptr(&field_type->name))); |
| | 2107 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| | 2108 | return ErrorSemanticAnalyzeFail; |
| | 2109 | } else if (struct_type->data.structure.layout == ContainerLayoutPacked) { |
| | 2110 | if ((err = emit_error_unless_type_allowed_in_packed_struct(g, field_type, field_node))) { |
| | 2111 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| | 2112 | return ErrorSemanticAnalyzeFail; |
| | 2113 | } |
| | 2114 | } |
| | 2115 | |
| 2100 | type_struct_field->src_index = i; | 2116 | type_struct_field->src_index = i; |
| 2101 | type_struct_field->gen_index = SIZE_MAX; | 2117 | type_struct_field->gen_index = SIZE_MAX; |
| 2102 | | 2118 | |
| ... | @@ -2171,49 +2187,39 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) { | ... | @@ -2171,49 +2187,39 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) { |
| 2171 | struct_type->data.structure.resolve_loop_flag = true; | 2187 | struct_type->data.structure.resolve_loop_flag = true; |
| 2172 | assert(decl_node->type == NodeTypeContainerDecl); | 2188 | assert(decl_node->type == NodeTypeContainerDecl); |
| 2173 | | 2189 | |
| 2174 | size_t abi_align = 0; | | |
| 2175 | size_t field_count = struct_type->data.structure.src_field_count; | 2190 | size_t field_count = struct_type->data.structure.src_field_count; |
| 2176 | bool packed = struct_type->data.structure.layout == ContainerLayoutPacked; | 2191 | bool packed = struct_type->data.structure.layout == ContainerLayoutPacked; |
| 2177 | | 2192 | |
| 2178 | for (size_t i = 0; i < field_count; i += 1) { | 2193 | for (size_t i = 0; i < field_count; i += 1) { |
| 2179 | AstNode *field_source_node = decl_node->data.container_decl.fields.at(i); | | |
| 2180 | TypeStructField *field = &struct_type->data.structure.fields[i]; | 2194 | TypeStructField *field = &struct_type->data.structure.fields[i]; |
| 2181 | ZigType *field_type = field->type_entry; | | |
| 2182 | assert(field_type != nullptr); | | |
| 2183 | | | |
| 2184 | if ((err = type_resolve(g, field_type, ResolveStatusAlignmentKnown))) { | | |
| 2185 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; | | |
| 2186 | return ErrorSemanticAnalyzeFail; | | |
| 2187 | } | | |
| 2188 | | | |
| 2189 | if (struct_type->data.structure.layout == ContainerLayoutExtern && | | |
| 2190 | !type_allowed_in_extern(g, field_type)) | | |
| 2191 | { | | |
| 2192 | add_node_error(g, field_source_node, | | |
| 2193 | buf_sprintf("extern structs cannot contain fields of type '%s'", | | |
| 2194 | buf_ptr(&field_type->name))); | | |
| 2195 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; | | |
| 2196 | return ErrorSemanticAnalyzeFail; | | |
| 2197 | } else if (packed) { | | |
| 2198 | if ((err = emit_error_unless_type_allowed_in_packed_struct(g, field_type, field_source_node))) { | | |
| 2199 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; | | |
| 2200 | return ErrorSemanticAnalyzeFail; | | |
| 2201 | } | | |
| 2202 | } | | |
| 2203 | | | |
| 2204 | if (field->gen_index == SIZE_MAX) | 2195 | if (field->gen_index == SIZE_MAX) |
| 2205 | continue; | 2196 | continue; |
| 2206 | | 2197 | |
| | 2198 | size_t this_field_align; |
| 2207 | if (packed) { | 2199 | if (packed) { |
| 2208 | // TODO: https://github.com/ziglang/zig/issues/1512 | 2200 | // TODO: https://github.com/ziglang/zig/issues/1512 |
| 2209 | if (1 > abi_align) { | 2201 | this_field_align = 1; |
| 2210 | abi_align = 1; | 2202 | // TODO If we have no type_entry for the field, we've already failed to |
| 2211 | } | 2203 | // compile the program correctly. This stage1 compiler needs a deeper |
| | 2204 | // reworking to make this correct, or we can ignore the problem |
| | 2205 | // and make sure it is fixed in stage2. This workaround is for when |
| | 2206 | // there is a false positive of a dependency loop, of alignment depending |
| | 2207 | // on itself. When this false positive happens we assume a pointer-aligned |
| | 2208 | // field, which is usually fine but could be incorrectly over-aligned or |
| | 2209 | // even under-aligned. See https://github.com/ziglang/zig/issues/1512 |
| | 2210 | } else if (field->type_entry == nullptr) { |
| | 2211 | this_field_align = g->builtin_types.entry_usize->abi_align; |
| 2212 | } else { | 2212 | } else { |
| 2213 | // TODO: https://github.com/ziglang/zig/issues/1512 | 2213 | if ((err = type_resolve(g, field->type_entry, ResolveStatusAlignmentKnown))) { |
| 2214 | if (field_type->abi_align > abi_align) { | 2214 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| 2215 | abi_align = field_type->abi_align; | 2215 | return ErrorSemanticAnalyzeFail; |
| 2216 | } | 2216 | } |
| | 2217 | this_field_align = field->type_entry->abi_align; |
| | 2218 | } |
| | 2219 | |
| | 2220 | // TODO: https://github.com/ziglang/zig/issues/1512 |
| | 2221 | if (this_field_align > struct_type->abi_align) { |
| | 2222 | struct_type->abi_align = this_field_align; |
| 2217 | } | 2223 | } |
| 2218 | } | 2224 | } |
| 2219 | | 2225 | |
| ... | @@ -2224,7 +2230,6 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) { | ... | @@ -2224,7 +2230,6 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) { |
| 2224 | } | 2230 | } |
| 2225 | | 2231 | |
| 2226 | struct_type->data.structure.resolve_status = ResolveStatusAlignmentKnown; | 2232 | struct_type->data.structure.resolve_status = ResolveStatusAlignmentKnown; |
| 2227 | struct_type->abi_align = abi_align; | | |
| 2228 | return ErrorNone; | 2233 | return ErrorNone; |
| 2229 | } | 2234 | } |
| 2230 | | 2235 | |