aboutsummaryrefslogtreecommitdiff
path: root/src/analyze.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2019-04-02 17:40:01 -0400
committerAndrew Kelley <andrew@ziglang.org>2019-04-02 18:31:19 -0400
commit9780fd59f063d23e69ceadf4305453531b704c11 (patch)
tree175b9977bca02b13a61521e1a1ec483f4eb77380 /src/analyze.cpp
parentcb0241fe44e347bd14fd5568a240f1237dafacc3 (diff)
downloadzig-9780fd59f063d23e69ceadf4305453531b704c11.tar.gz
zig-9780fd59f063d23e69ceadf4305453531b704c11.zip
put the alignment hack in for unions too. fixes std tests
Diffstat (limited to 'src/analyze.cpp')
-rw-r--r--src/analyze.cpp35
1 files changed, 23 insertions, 12 deletions
diff --git a/src/analyze.cpp b/src/analyze.cpp
index c3fb774a50..69a69b51a1 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -1742,26 +1742,36 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) {
ZigType *most_aligned_union_member = nullptr;
uint32_t field_count = union_type->data.unionation.src_field_count;
+ bool packed = union_type->data.unionation.layout == ContainerLayoutPacked;
for (uint32_t i = 0; i < field_count; i += 1) {
- TypeUnionField *union_field = &union_type->data.unionation.fields[i];
- ZigType *field_type = union_field->type_entry;
+ TypeUnionField *field = &union_type->data.unionation.fields[i];
+ if (field->gen_index == UINT32_MAX)
+ continue;
- if ((err = type_resolve(g, field_type, ResolveStatusAlignmentKnown))) {
- union_type->data.unionation.resolve_status = ResolveStatusInvalid;
- return ErrorSemanticAnalyzeFail;
- }
+ size_t this_field_align;
+ if (packed) {
+ // TODO: https://github.com/ziglang/zig/issues/1512
+ this_field_align = 1;
+ // This is the same hack as resolve_struct_alignment. See the comment there.
+ } else if (field->type_entry == nullptr) {
+ this_field_align = g->builtin_types.entry_usize->abi_align;
+ } else {
+ if ((err = type_resolve(g, field->type_entry, ResolveStatusAlignmentKnown))) {
+ union_type->data.unionation.resolve_status = ResolveStatusInvalid;
+ return ErrorSemanticAnalyzeFail;
+ }
- if (type_is_invalid(union_type))
- return ErrorSemanticAnalyzeFail;
+ if (union_type->data.unionation.resolve_status == ResolveStatusInvalid)
+ return ErrorSemanticAnalyzeFail;
- if (!type_has_bits(field_type))
- continue;
+ this_field_align = field->type_entry->abi_align;
+ }
if (most_aligned_union_member == nullptr ||
- field_type->abi_align > most_aligned_union_member->abi_align)
+ this_field_align > most_aligned_union_member->abi_align)
{
- most_aligned_union_member = field_type;
+ most_aligned_union_member = field->type_entry;
}
}
@@ -2395,6 +2405,7 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {
TypeUnionField *union_field = &union_type->data.unionation.fields[i];
union_field->name = field_node->data.struct_field.name;
union_field->decl_node = field_node;
+ union_field->gen_index = UINT32_MAX;
auto field_entry = union_type->data.unionation.fields_by_name.put_unique(union_field->name, union_field);
if (field_entry != nullptr) {