| ... | ... | @@ -2038,6 +2038,8 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { |
| 2038 | 2038 | static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) { |
| 2039 | 2039 | assert(struct_type->id == ZigTypeIdStruct); |
| 2040 | 2040 | |
| 2041 | Error err; |
| 2042 | |
| 2041 | 2043 | if (struct_type->data.structure.resolve_status == ResolveStatusInvalid) |
| 2042 | 2044 | return ErrorSemanticAnalyzeFail; |
| 2043 | 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 | 2049 | assert(decl_node->type == NodeTypeContainerDecl); |
| 2048 | 2050 | |
| 2049 | 2051 | if (struct_type->data.structure.resolve_loop_flag) { |
| 2050 | | if (struct_type->data.structure.resolve_status != ResolveStatusInvalid) { |
| 2051 | | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| 2052 | | ErrorMsg *msg = add_node_error(g, decl_node, |
| 2053 | | buf_sprintf("struct '%s' depends on its own size", buf_ptr(&struct_type->name))); |
| 2054 | | emit_error_notes_for_ref_stack(g, msg); |
| 2055 | | } |
| 2056 | | return ErrorSemanticAnalyzeFail; |
| 2052 | // TODO This is a problem. I believe it can be solved with lazy values. |
| 2053 | struct_type->size_in_bits = SIZE_MAX;; |
| 2054 | struct_type->abi_size = SIZE_MAX;; |
| 2055 | struct_type->data.structure.resolve_status = ResolveStatusZeroBitsKnown; |
| 2056 | struct_type->data.structure.resolve_loop_flag = false; |
| 2057 | return ErrorNone; |
| 2057 | 2058 | } |
| 2058 | 2059 | |
| 2059 | 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 | 2098 | if (struct_type->data.structure.resolve_status == ResolveStatusInvalid) |
| 2098 | 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 | 2116 | type_struct_field->src_index = i; |
| 2101 | 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 | 2187 | struct_type->data.structure.resolve_loop_flag = true; |
| 2172 | 2188 | assert(decl_node->type == NodeTypeContainerDecl); |
| 2173 | 2189 | |
| 2174 | | size_t abi_align = 0; |
| 2175 | 2190 | size_t field_count = struct_type->data.structure.src_field_count; |
| 2176 | 2191 | bool packed = struct_type->data.structure.layout == ContainerLayoutPacked; |
| 2177 | 2192 | |
| 2178 | 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 | 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 | 2195 | if (field->gen_index == SIZE_MAX) |
| 2205 | 2196 | continue; |
| 2206 | 2197 | |
| 2198 | size_t this_field_align; |
| 2207 | 2199 | if (packed) { |
| 2208 | 2200 | // TODO: https://github.com/ziglang/zig/issues/1512 |
| 2209 | | if (1 > abi_align) { |
| 2210 | | abi_align = 1; |
| 2211 | | } |
| 2201 | this_field_align = 1; |
| 2202 | // TODO If we have no type_entry for the field, we've already failed to |
| 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 | 2212 | } else { |
| 2213 | | // TODO: https://github.com/ziglang/zig/issues/1512 |
| 2214 | | if (field_type->abi_align > abi_align) { |
| 2215 | | abi_align = field_type->abi_align; |
| 2213 | if ((err = type_resolve(g, field->type_entry, ResolveStatusAlignmentKnown))) { |
| 2214 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| 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 | 2230 | } |
| 2225 | 2231 | |
| 2226 | 2232 | struct_type->data.structure.resolve_status = ResolveStatusAlignmentKnown; |
| 2227 | | struct_type->abi_align = abi_align; |
| 2228 | 2233 | return ErrorNone; |
| 2229 | 2234 | } |
| 2230 | 2235 | |