authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-25 11:34:07-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-25 11:34:07-04:00
logfa6c20a02d2ee7648f69d9ba3b19fa600e8dd0e9
tree2453616dd22b5c3fc14c07eea88b0dcc8c158a43
parentd277a1196b85cf51a22f7c6b41ad0df7804c71bd
signaturelock-open Commit is signed but in an unrecognized format.

hook up unions with lazy values

this case works now: ```zig const Expr = union(enum) { Literal: u8, Question: *Expr, }; ```

3 files changed, 112 insertions(+), 78 deletions(-)

src/all_types.hpp+6-3
...@@ -489,10 +489,12 @@ struct TypeEnumField {...@@ -489,10 +489,12 @@ struct TypeEnumField {
489489
490struct TypeUnionField {490struct TypeUnionField {
491 Buf *name;491 Buf *name;
492 ZigType *type_entry; // available after ResolveStatusSizeKnown
493 ConstExprValue *type_val; // available after ResolveStatusZeroBitsKnown
492 TypeEnumField *enum_field;494 TypeEnumField *enum_field;
493 ZigType *type_entry;
494 AstNode *decl_node;495 AstNode *decl_node;
495 uint32_t gen_index;496 uint32_t gen_index;
497 uint32_t align;
496};498};
497499
498enum NodeType {500enum NodeType {
...@@ -1247,7 +1249,7 @@ struct ZigTypeUnion {...@@ -1247,7 +1249,7 @@ struct ZigTypeUnion {
1247 HashMap<Buf *, TypeUnionField *, buf_hash, buf_eql_buf> fields_by_name;1249 HashMap<Buf *, TypeUnionField *, buf_hash, buf_eql_buf> fields_by_name;
1248 ZigType *tag_type; // always an enum or null1250 ZigType *tag_type; // always an enum or null
1249 LLVMTypeRef union_llvm_type;1251 LLVMTypeRef union_llvm_type;
1250 ZigType *most_aligned_union_member;1252 TypeUnionField *most_aligned_union_member;
1251 size_t gen_union_index;1253 size_t gen_union_index;
1252 size_t gen_tag_index;1254 size_t gen_tag_index;
1253 size_t union_abi_size;1255 size_t union_abi_size;
...@@ -1262,7 +1264,8 @@ struct ZigTypeUnion {...@@ -1262,7 +1264,8 @@ struct ZigTypeUnion {
1262 // whether any of the fields require comptime1264 // whether any of the fields require comptime
1263 // the value is not valid until zero_bits_known == true1265 // the value is not valid until zero_bits_known == true
1264 bool requires_comptime;1266 bool requires_comptime;
1265 bool resolve_loop_flag;1267 bool resolve_loop_flag_zero_bits;
1268 bool resolve_loop_flag_other;
1266};1269};
12671270
1268struct FnGenParamInfo {1271struct FnGenParamInfo {
src/analyze.cpp+105-74
...@@ -961,10 +961,12 @@ static Error type_val_resolve_zero_bits(CodeGen *g, ConstExprValue *type_val, Zi...@@ -961,10 +961,12 @@ static Error type_val_resolve_zero_bits(CodeGen *g, ConstExprValue *type_val, Zi
961 Error err;961 Error err;
962 if (type_val->special != ConstValSpecialLazy) {962 if (type_val->special != ConstValSpecialLazy) {
963 assert(type_val->special == ConstValSpecialStatic);963 assert(type_val->special == ConstValSpecialStatic);
964 if (type_val->data.x_type->id == ZigTypeIdStruct &&964 if ((type_val->data.x_type->id == ZigTypeIdStruct &&
965 type_val->data.x_type->data.structure.resolve_loop_flag_zero_bits)965 type_val->data.x_type->data.structure.resolve_loop_flag_zero_bits) ||
966 (type_val->data.x_type->id == ZigTypeIdUnion &&
967 type_val->data.x_type->data.unionation.resolve_loop_flag_zero_bits))
966 {968 {
967 // Does a struct which contains a pointer field to itself have bits? Yes.969 // Does a struct/union which contains a pointer field to itself have bits? Yes.
968 *is_zero_bits = false;970 *is_zero_bits = false;
969 return ErrorNone;971 return ErrorNone;
970 }972 }
...@@ -1079,7 +1081,7 @@ static ReqCompTime type_val_resolve_requires_comptime(CodeGen *g, ConstExprValue...@@ -1079,7 +1081,7 @@ static ReqCompTime type_val_resolve_requires_comptime(CodeGen *g, ConstExprValue
1079 zig_unreachable();1081 zig_unreachable();
1080}1082}
10811083
1082static Error type_val_resolve_abi_align(CodeGen *g, ConstExprValue *type_val, size_t *abi_align) {1084static Error type_val_resolve_abi_align(CodeGen *g, ConstExprValue *type_val, uint32_t *abi_align) {
1083 Error err;1085 Error err;
1084 if (type_val->special != ConstValSpecialLazy) {1086 if (type_val->special != ConstValSpecialLazy) {
1085 assert(type_val->special == ConstValSpecialStatic);1087 assert(type_val->special == ConstValSpecialStatic);
...@@ -1917,7 +1919,7 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) {...@@ -1917,7 +1919,7 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) {
19171919
1918 AstNode *decl_node = union_type->data.structure.decl_node;1920 AstNode *decl_node = union_type->data.structure.decl_node;
19191921
1920 if (union_type->data.unionation.resolve_loop_flag) {1922 if (union_type->data.unionation.resolve_loop_flag_other) {
1921 if (union_type->data.unionation.resolve_status != ResolveStatusInvalid) {1923 if (union_type->data.unionation.resolve_status != ResolveStatusInvalid) {
1922 union_type->data.unionation.resolve_status = ResolveStatusInvalid;1924 union_type->data.unionation.resolve_status = ResolveStatusInvalid;
1923 g->trace_err = add_node_error(g, decl_node,1925 g->trace_err = add_node_error(g, decl_node,
...@@ -1927,9 +1929,9 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) {...@@ -1927,9 +1929,9 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) {
1927 }1929 }
19281930
1929 // set temporary flag1931 // set temporary flag
1930 union_type->data.unionation.resolve_loop_flag = true;1932 union_type->data.unionation.resolve_loop_flag_other = true;
19311933
1932 ZigType *most_aligned_union_member = nullptr;1934 TypeUnionField *most_aligned_union_member = nullptr;
1933 uint32_t field_count = union_type->data.unionation.src_field_count;1935 uint32_t field_count = union_type->data.unionation.src_field_count;
1934 bool packed = union_type->data.unionation.layout == ContainerLayoutPacked;1936 bool packed = union_type->data.unionation.layout == ContainerLayoutPacked;
19351937
...@@ -1938,33 +1940,32 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) {...@@ -1938,33 +1940,32 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) {
1938 if (field->gen_index == UINT32_MAX)1940 if (field->gen_index == UINT32_MAX)
1939 continue;1941 continue;
19401942
1941 src_assert(field->type_entry != nullptr, decl_node);1943 AstNode *align_expr = field->decl_node->data.struct_field.align_expr;
19421944 if (align_expr != nullptr) {
1943 size_t this_field_align;1945 if (!analyze_const_align(g, &union_type->data.unionation.decls_scope->base, align_expr,
1944 if (packed) {1946 &field->align))
1945 // TODO: https://github.com/ziglang/zig/issues/15121947 {
1946 this_field_align = 1;1948 union_type->data.unionation.resolve_status = ResolveStatusInvalid;
1949 return err;
1950 }
1951 } else if (packed) {
1952 field->align = 1;
1947 } else {1953 } else {
1948 if ((err = type_resolve(g, field->type_entry, ResolveStatusAlignmentKnown))) {1954 if ((err = type_val_resolve_abi_align(g, field->type_val, &field->align))) {
1949 union_type->data.unionation.resolve_status = ResolveStatusInvalid;1955 union_type->data.unionation.resolve_status = ResolveStatusInvalid;
1950 return ErrorSemanticAnalyzeFail;1956 return err;
1951 }1957 }
1952
1953 if (union_type->data.unionation.resolve_status == ResolveStatusInvalid)1958 if (union_type->data.unionation.resolve_status == ResolveStatusInvalid)
1954 return ErrorSemanticAnalyzeFail;1959 return ErrorSemanticAnalyzeFail;
1955
1956 this_field_align = field->type_entry->abi_align;
1957 }1960 }
19581961
1959 if (most_aligned_union_member == nullptr ||1962 if (most_aligned_union_member == nullptr || field->align > most_aligned_union_member->align) {
1960 this_field_align > most_aligned_union_member->abi_align)1963 most_aligned_union_member = field;
1961 {
1962 most_aligned_union_member = field->type_entry;
1963 }1964 }
1964 }1965 }
19651966
1966 // unset temporary flag1967 // unset temporary flag
1967 union_type->data.unionation.resolve_loop_flag = false;1968 union_type->data.unionation.resolve_loop_flag_other = false;
1968 union_type->data.unionation.resolve_status = ResolveStatusAlignmentKnown;1969 union_type->data.unionation.resolve_status = ResolveStatusAlignmentKnown;
1969 union_type->data.unionation.most_aligned_union_member = most_aligned_union_member;1970 union_type->data.unionation.most_aligned_union_member = most_aligned_union_member;
19701971
...@@ -1978,18 +1979,18 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) {...@@ -1978,18 +1979,18 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) {
1978 union_type->abi_align = tag_type->abi_align;1979 union_type->abi_align = tag_type->abi_align;
1979 union_type->data.unionation.gen_tag_index = SIZE_MAX;1980 union_type->data.unionation.gen_tag_index = SIZE_MAX;
1980 union_type->data.unionation.gen_union_index = SIZE_MAX;1981 union_type->data.unionation.gen_union_index = SIZE_MAX;
1981 } else if (tag_type->abi_align > most_aligned_union_member->abi_align) {1982 } else if (tag_type->abi_align > most_aligned_union_member->align) {
1982 union_type->abi_align = tag_type->abi_align;1983 union_type->abi_align = tag_type->abi_align;
1983 union_type->data.unionation.gen_tag_index = 0;1984 union_type->data.unionation.gen_tag_index = 0;
1984 union_type->data.unionation.gen_union_index = 1;1985 union_type->data.unionation.gen_union_index = 1;
1985 } else {1986 } else {
1986 union_type->abi_align = most_aligned_union_member->abi_align;1987 union_type->abi_align = most_aligned_union_member->align;
1987 union_type->data.unionation.gen_union_index = 0;1988 union_type->data.unionation.gen_union_index = 0;
1988 union_type->data.unionation.gen_tag_index = 1;1989 union_type->data.unionation.gen_tag_index = 1;
1989 }1990 }
1990 } else {1991 } else {
1991 assert(most_aligned_union_member != nullptr);1992 assert(most_aligned_union_member != nullptr);
1992 union_type->abi_align = most_aligned_union_member->abi_align;1993 union_type->abi_align = most_aligned_union_member->align;
1993 union_type->data.unionation.gen_union_index = SIZE_MAX;1994 union_type->data.unionation.gen_union_index = SIZE_MAX;
1994 union_type->data.unionation.gen_tag_index = SIZE_MAX;1995 union_type->data.unionation.gen_tag_index = SIZE_MAX;
1995 }1996 }
...@@ -2016,14 +2017,14 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) {...@@ -2016,14 +2017,14 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) {
2016 assert(decl_node->type == NodeTypeContainerDecl);2017 assert(decl_node->type == NodeTypeContainerDecl);
20172018
2018 uint32_t field_count = union_type->data.unionation.src_field_count;2019 uint32_t field_count = union_type->data.unionation.src_field_count;
2019 ZigType *most_aligned_union_member = union_type->data.unionation.most_aligned_union_member;2020 TypeUnionField *most_aligned_union_member = union_type->data.unionation.most_aligned_union_member;
20202021
2021 assert(union_type->data.unionation.fields);2022 assert(union_type->data.unionation.fields);
20222023
2023 size_t union_abi_size = 0;2024 size_t union_abi_size = 0;
2024 size_t union_size_in_bits = 0;2025 size_t union_size_in_bits = 0;
20252026
2026 if (union_type->data.unionation.resolve_loop_flag) {2027 if (union_type->data.unionation.resolve_loop_flag_other) {
2027 if (union_type->data.unionation.resolve_status != ResolveStatusInvalid) {2028 if (union_type->data.unionation.resolve_status != ResolveStatusInvalid) {
2028 union_type->data.unionation.resolve_status = ResolveStatusInvalid;2029 union_type->data.unionation.resolve_status = ResolveStatusInvalid;
2029 g->trace_err = add_node_error(g, decl_node,2030 g->trace_err = add_node_error(g, decl_node,
...@@ -2033,11 +2034,18 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) {...@@ -2033,11 +2034,18 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) {
2033 }2034 }
20342035
2035 // set temporary flag2036 // set temporary flag
2036 union_type->data.unionation.resolve_loop_flag = true;2037 union_type->data.unionation.resolve_loop_flag_other = true;
20372038
2038 for (uint32_t i = 0; i < field_count; i += 1) {2039 for (uint32_t i = 0; i < field_count; i += 1) {
2040 AstNode *field_source_node = decl_node->data.container_decl.fields.at(i);
2039 TypeUnionField *union_field = &union_type->data.unionation.fields[i];2041 TypeUnionField *union_field = &union_type->data.unionation.fields[i];
2040 ZigType *field_type = union_field->type_entry;2042
2043 if ((err = ir_resolve_lazy(g, field_source_node, union_field->type_val))) {
2044 union_type->data.unionation.resolve_status = ResolveStatusInvalid;
2045 return err;
2046 }
2047 ZigType *field_type = union_field->type_val->data.x_type;
2048 union_field->type_entry = field_type;
20412049
2042 if ((err = type_resolve(g, field_type, ResolveStatusSizeKnown))) {2050 if ((err = type_resolve(g, field_type, ResolveStatusSizeKnown))) {
2043 union_type->data.unionation.resolve_status = ResolveStatusInvalid;2051 union_type->data.unionation.resolve_status = ResolveStatusInvalid;
...@@ -2057,11 +2065,11 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) {...@@ -2057,11 +2065,11 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) {
2057 // The union itself for now has to be treated as being independently aligned.2065 // The union itself for now has to be treated as being independently aligned.
2058 // See https://github.com/ziglang/zig/issues/2166.2066 // See https://github.com/ziglang/zig/issues/2166.
2059 if (most_aligned_union_member != nullptr) {2067 if (most_aligned_union_member != nullptr) {
2060 union_abi_size = align_forward(union_abi_size, most_aligned_union_member->abi_align);2068 union_abi_size = align_forward(union_abi_size, most_aligned_union_member->align);
2061 }2069 }
20622070
2063 // unset temporary flag2071 // unset temporary flag
2064 union_type->data.unionation.resolve_loop_flag = false;2072 union_type->data.unionation.resolve_loop_flag_other = false;
2065 union_type->data.unionation.resolve_status = ResolveStatusSizeKnown;2073 union_type->data.unionation.resolve_status = ResolveStatusSizeKnown;
2066 union_type->data.unionation.union_abi_size = union_abi_size;2074 union_type->data.unionation.union_abi_size = union_abi_size;
20672075
...@@ -2080,7 +2088,7 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) {...@@ -2080,7 +2088,7 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) {
2080 field_sizes[union_type->data.unionation.gen_tag_index] = tag_type->abi_size;2088 field_sizes[union_type->data.unionation.gen_tag_index] = tag_type->abi_size;
2081 field_aligns[union_type->data.unionation.gen_tag_index] = tag_type->abi_align;2089 field_aligns[union_type->data.unionation.gen_tag_index] = tag_type->abi_align;
2082 field_sizes[union_type->data.unionation.gen_union_index] = union_abi_size;2090 field_sizes[union_type->data.unionation.gen_union_index] = union_abi_size;
2083 field_aligns[union_type->data.unionation.gen_union_index] = most_aligned_union_member->abi_align;2091 field_aligns[union_type->data.unionation.gen_union_index] = most_aligned_union_member->align;
2084 size_t field2_offset = next_field_offset(0, union_type->abi_align, field_sizes[0], field_aligns[1]);2092 size_t field2_offset = next_field_offset(0, union_type->abi_align, field_sizes[0], field_aligns[1]);
2085 union_type->abi_size = next_field_offset(field2_offset, union_type->abi_align, field_sizes[1], union_type->abi_align);2093 union_type->abi_size = next_field_offset(field2_offset, union_type->abi_align, field_sizes[1], union_type->abi_align);
2086 union_type->size_in_bits = union_type->abi_size * 8;2094 union_type->size_in_bits = union_type->abi_size * 8;
...@@ -2449,12 +2457,12 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) {...@@ -2449,12 +2457,12 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) {
2449 } else if (packed) {2457 } else if (packed) {
2450 field->align = 1;2458 field->align = 1;
2451 } else {2459 } else {
2452 size_t result_abi_align;2460 if ((err = type_val_resolve_abi_align(g, field->type_val, &field->align))) {
2453 if ((err = type_val_resolve_abi_align(g, field->type_val, &result_abi_align))) {
2454 struct_type->data.structure.resolve_status = ResolveStatusInvalid;2461 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2455 return err;2462 return err;
2456 }2463 }
2457 field->align = result_abi_align;2464 if (struct_type->data.structure.resolve_status == ResolveStatusInvalid)
2465 return ErrorSemanticAnalyzeFail;
2458 }2466 }
24592467
2460 if (field->align > struct_type->abi_align) {2468 if (field->align > struct_type->abi_align) {
...@@ -2486,7 +2494,7 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {...@@ -2486,7 +2494,7 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {
2486 AstNode *decl_node = union_type->data.unionation.decl_node;2494 AstNode *decl_node = union_type->data.unionation.decl_node;
2487 assert(decl_node->type == NodeTypeContainerDecl);2495 assert(decl_node->type == NodeTypeContainerDecl);
24882496
2489 if (union_type->data.unionation.resolve_loop_flag) {2497 if (union_type->data.unionation.resolve_loop_flag_zero_bits) {
2490 if (union_type->data.unionation.resolve_status != ResolveStatusInvalid) {2498 if (union_type->data.unionation.resolve_status != ResolveStatusInvalid) {
2491 union_type->data.unionation.resolve_status = ResolveStatusInvalid;2499 union_type->data.unionation.resolve_status = ResolveStatusInvalid;
2492 g->trace_err = add_node_error(g, decl_node,2500 g->trace_err = add_node_error(g, decl_node,
...@@ -2496,7 +2504,7 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {...@@ -2496,7 +2504,7 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {
2496 return ErrorSemanticAnalyzeFail;2504 return ErrorSemanticAnalyzeFail;
2497 }2505 }
24982506
2499 union_type->data.unionation.resolve_loop_flag = true;2507 union_type->data.unionation.resolve_loop_flag_zero_bits = true;
25002508
2501 assert(union_type->data.unionation.fields == nullptr);2509 assert(union_type->data.unionation.fields == nullptr);
2502 uint32_t field_count = (uint32_t)decl_node->data.container_decl.fields.length;2510 uint32_t field_count = (uint32_t)decl_node->data.container_decl.fields.length;
...@@ -2605,49 +2613,68 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {...@@ -2605,49 +2613,68 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {
2605 return ErrorSemanticAnalyzeFail;2613 return ErrorSemanticAnalyzeFail;
2606 }2614 }
26072615
2608 ZigType *field_type;2616 bool field_is_zero_bits;
2609 if (field_node->data.struct_field.type == nullptr) {2617 if (field_node->data.struct_field.type == nullptr) {
2610 if (decl_node->data.container_decl.auto_enum || decl_node->data.container_decl.init_arg_expr != nullptr) {2618 if (decl_node->data.container_decl.auto_enum ||
2611 field_type = g->builtin_types.entry_void;2619 decl_node->data.container_decl.init_arg_expr != nullptr)
2620 {
2621 union_field->type_entry = g->builtin_types.entry_void;
2622 field_is_zero_bits = false;
2612 } else {2623 } else {
2613 add_node_error(g, field_node, buf_sprintf("union field missing type"));2624 add_node_error(g, field_node, buf_sprintf("union field missing type"));
2614 union_type->data.unionation.resolve_status = ResolveStatusInvalid;2625 union_type->data.unionation.resolve_status = ResolveStatusInvalid;
2615 return ErrorSemanticAnalyzeFail;2626 return ErrorSemanticAnalyzeFail;
2616 }2627 }
2617 } else {2628 } else {
2618 field_type = analyze_type_expr(g, scope, field_node->data.struct_field.type);2629 ConstExprValue *field_type_val = analyze_const_value_allow_lazy(g, scope,
2619 if ((err = type_resolve(g, field_type, ResolveStatusAlignmentKnown))) {2630 field_node->data.struct_field.type, g->builtin_types.entry_type, nullptr, true);
2631 if (type_is_invalid(field_type_val->type)) {
2620 union_type->data.unionation.resolve_status = ResolveStatusInvalid;2632 union_type->data.unionation.resolve_status = ResolveStatusInvalid;
2621 return ErrorSemanticAnalyzeFail;2633 return ErrorSemanticAnalyzeFail;
2622 }2634 }
2635 assert(field_type_val->special != ConstValSpecialRuntime);
2636 union_field->type_val = field_type_val;
2623 if (union_type->data.unionation.resolve_status == ResolveStatusInvalid)2637 if (union_type->data.unionation.resolve_status == ResolveStatusInvalid)
2624 return ErrorSemanticAnalyzeFail;2638 return ErrorSemanticAnalyzeFail;
2625 }
2626 union_field->type_entry = field_type;
26272639
2628 if (field_type->id == ZigTypeIdOpaque) {2640 bool field_is_opaque_type;
2629 add_node_error(g, field_node->data.struct_field.type,2641 if ((err = type_val_resolve_is_opaque_type(g, field_type_val, &field_is_opaque_type))) {
2630 buf_sprintf("opaque types have unknown size and therefore cannot be directly embedded in unions"));2642 union_type->data.unionation.resolve_status = ResolveStatusInvalid;
2631 union_type->data.unionation.resolve_status = ResolveStatusInvalid;2643 return ErrorSemanticAnalyzeFail;
2632 return ErrorSemanticAnalyzeFail;2644 }
2633 }2645 if (field_is_opaque_type) {
2646 add_node_error(g, field_node->data.struct_field.type,
2647 buf_create_from_str(
2648 "opaque types have unknown size and therefore cannot be directly embedded in unions"));
2649 union_type->data.unionation.resolve_status = ResolveStatusInvalid;
2650 return ErrorSemanticAnalyzeFail;
2651 }
26342652
2635 switch (type_requires_comptime(g, field_type)) {2653 switch (type_val_resolve_requires_comptime(g, field_type_val)) {
2636 case ReqCompTimeInvalid:2654 case ReqCompTimeInvalid:
2655 if (g->trace_err != nullptr) {
2656 g->trace_err = add_error_note(g, g->trace_err, field_node,
2657 buf_create_from_str("while checking this field"));
2658 }
2659 union_type->data.unionation.resolve_status = ResolveStatusInvalid;
2660 return ErrorSemanticAnalyzeFail;
2661 case ReqCompTimeYes:
2662 union_type->data.unionation.requires_comptime = true;
2663 break;
2664 case ReqCompTimeNo:
2665 break;
2666 }
2667
2668 if ((err = type_val_resolve_zero_bits(g, field_type_val, union_type, nullptr, &field_is_zero_bits))) {
2637 union_type->data.unionation.resolve_status = ResolveStatusInvalid;2669 union_type->data.unionation.resolve_status = ResolveStatusInvalid;
2638 return ErrorSemanticAnalyzeFail;2670 return ErrorSemanticAnalyzeFail;
2639 case ReqCompTimeYes:2671 }
2640 union_type->data.unionation.requires_comptime = true;
2641 break;
2642 case ReqCompTimeNo:
2643 break;
2644 }2672 }
26452673
2646 if (field_node->data.struct_field.value != nullptr && !decl_node->data.container_decl.auto_enum) {2674 if (field_node->data.struct_field.value != nullptr && !decl_node->data.container_decl.auto_enum) {
2647 ErrorMsg *msg = add_node_error(g, field_node->data.struct_field.value,2675 ErrorMsg *msg = add_node_error(g, field_node->data.struct_field.value,
2648 buf_sprintf("non-enum union field assignment"));2676 buf_create_from_str("untagged union field assignment"));
2649 add_error_note(g, msg, decl_node,2677 add_error_note(g, msg, decl_node, buf_create_from_str("consider 'union(enum)' here"));
2650 buf_sprintf("consider 'union(enum)' here"));
2651 }2678 }
26522679
2653 if (create_enum_type) {2680 if (create_enum_type) {
...@@ -2706,7 +2733,7 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {...@@ -2706,7 +2733,7 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {
2706 }2733 }
2707 assert(union_field->enum_field != nullptr);2734 assert(union_field->enum_field != nullptr);
27082735
2709 if (!type_has_bits(field_type))2736 if (field_is_zero_bits)
2710 continue;2737 continue;
27112738
2712 union_field->gen_index = gen_field_index;2739 union_field->gen_index = gen_field_index;
...@@ -2783,7 +2810,7 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {...@@ -2783,7 +2810,7 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {
2783 return ErrorSemanticAnalyzeFail;2810 return ErrorSemanticAnalyzeFail;
2784 }2811 }
27852812
2786 union_type->data.unionation.resolve_loop_flag = false;2813 union_type->data.unionation.resolve_loop_flag_zero_bits = false;
27872814
2788 union_type->data.unionation.gen_field_count = gen_field_index;2815 union_type->data.unionation.gen_field_count = gen_field_index;
2789 bool zero_bits = gen_field_index == 0 && (field_count < 2 || !src_have_tag);2816 bool zero_bits = gen_field_index == 0 && (field_count < 2 || !src_have_tag);
...@@ -5002,6 +5029,10 @@ ReqCompTime type_requires_comptime(CodeGen *g, ZigType *ty) {...@@ -5002,6 +5029,10 @@ ReqCompTime type_requires_comptime(CodeGen *g, ZigType *ty) {
5002 return ReqCompTimeInvalid;5029 return ReqCompTimeInvalid;
5003 return ty->data.structure.requires_comptime ? ReqCompTimeYes : ReqCompTimeNo;5030 return ty->data.structure.requires_comptime ? ReqCompTimeYes : ReqCompTimeNo;
5004 case ZigTypeIdUnion:5031 case ZigTypeIdUnion:
5032 if (ty->data.unionation.resolve_loop_flag_zero_bits) {
5033 // Does a union which contains a pointer field to itself require comptime? No.
5034 return ReqCompTimeNo;
5035 }
5005 if ((err = type_resolve(g, ty, ResolveStatusZeroBitsKnown)))5036 if ((err = type_resolve(g, ty, ResolveStatusZeroBitsKnown)))
5006 return ReqCompTimeInvalid;5037 return ReqCompTimeInvalid;
5007 return ty->data.unionation.requires_comptime ? ReqCompTimeYes : ReqCompTimeNo;5038 return ty->data.unionation.requires_comptime ? ReqCompTimeYes : ReqCompTimeNo;
...@@ -7308,7 +7339,7 @@ static void resolve_llvm_types_enum(CodeGen *g, ZigType *enum_type, ResolveStatu...@@ -7308,7 +7339,7 @@ static void resolve_llvm_types_enum(CodeGen *g, ZigType *enum_type, ResolveStatu
7308static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveStatus wanted_resolve_status) {7339static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveStatus wanted_resolve_status) {
7309 if (union_type->data.unionation.resolve_status >= wanted_resolve_status) return;7340 if (union_type->data.unionation.resolve_status >= wanted_resolve_status) return;
73107341
7311 ZigType *most_aligned_union_member = union_type->data.unionation.most_aligned_union_member;7342 TypeUnionField *most_aligned_union_member = union_type->data.unionation.most_aligned_union_member;
7312 ZigType *tag_type = union_type->data.unionation.tag_type;7343 ZigType *tag_type = union_type->data.unionation.tag_type;
7313 if (most_aligned_union_member == nullptr) {7344 if (most_aligned_union_member == nullptr) {
7314 union_type->llvm_type = get_llvm_type(g, tag_type);7345 union_type->llvm_type = get_llvm_type(g, tag_type);
...@@ -7361,17 +7392,17 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta...@@ -7361,17 +7392,17 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
7361 if (tag_type == nullptr || !type_has_bits(tag_type)) {7392 if (tag_type == nullptr || !type_has_bits(tag_type)) {
7362 assert(most_aligned_union_member != nullptr);7393 assert(most_aligned_union_member != nullptr);
73637394
7364 size_t padding_bytes = union_type->data.unionation.union_abi_size - most_aligned_union_member->abi_size;7395 size_t padding_bytes = union_type->data.unionation.union_abi_size - most_aligned_union_member->type_entry->abi_size;
7365 if (padding_bytes > 0) {7396 if (padding_bytes > 0) {
7366 ZigType *u8_type = get_int_type(g, false, 8);7397 ZigType *u8_type = get_int_type(g, false, 8);
7367 ZigType *padding_array = get_array_type(g, u8_type, padding_bytes);7398 ZigType *padding_array = get_array_type(g, u8_type, padding_bytes);
7368 LLVMTypeRef union_element_types[] = {7399 LLVMTypeRef union_element_types[] = {
7369 most_aligned_union_member->llvm_type,7400 most_aligned_union_member->type_entry->llvm_type,
7370 get_llvm_type(g, padding_array),7401 get_llvm_type(g, padding_array),
7371 };7402 };
7372 LLVMStructSetBody(union_type->llvm_type, union_element_types, 2, false);7403 LLVMStructSetBody(union_type->llvm_type, union_element_types, 2, false);
7373 } else {7404 } else {
7374 LLVMStructSetBody(union_type->llvm_type, &most_aligned_union_member->llvm_type, 1, false);7405 LLVMStructSetBody(union_type->llvm_type, &most_aligned_union_member->type_entry->llvm_type, 1, false);
7375 }7406 }
7376 union_type->data.unionation.union_llvm_type = union_type->llvm_type;7407 union_type->data.unionation.union_llvm_type = union_type->llvm_type;
7377 union_type->data.unionation.gen_tag_index = SIZE_MAX;7408 union_type->data.unionation.gen_tag_index = SIZE_MAX;
...@@ -7382,7 +7413,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta...@@ -7382,7 +7413,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
7382 ZigLLVMFileToScope(import->data.structure.root_struct->di_file), buf_ptr(&union_type->name),7413 ZigLLVMFileToScope(import->data.structure.root_struct->di_file), buf_ptr(&union_type->name),
7383 import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1),7414 import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1),
7384 union_type->data.unionation.union_abi_size * 8,7415 union_type->data.unionation.union_abi_size * 8,
7385 most_aligned_union_member->abi_align * 8,7416 most_aligned_union_member->align * 8,
7386 ZigLLVM_DIFlags_Zero, union_inner_di_types,7417 ZigLLVM_DIFlags_Zero, union_inner_di_types,
7387 gen_field_count, 0, "");7418 gen_field_count, 0, "");
73887419
...@@ -7393,14 +7424,14 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta...@@ -7393,14 +7424,14 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
7393 }7424 }
73947425
7395 LLVMTypeRef union_type_ref;7426 LLVMTypeRef union_type_ref;
7396 size_t padding_bytes = union_type->data.unionation.union_abi_size - most_aligned_union_member->abi_size;7427 size_t padding_bytes = union_type->data.unionation.union_abi_size - most_aligned_union_member->type_entry->abi_size;
7397 if (padding_bytes == 0) {7428 if (padding_bytes == 0) {
7398 union_type_ref = get_llvm_type(g, most_aligned_union_member);7429 union_type_ref = get_llvm_type(g, most_aligned_union_member->type_entry);
7399 } else {7430 } else {
7400 ZigType *u8_type = get_int_type(g, false, 8);7431 ZigType *u8_type = get_int_type(g, false, 8);
7401 ZigType *padding_array = get_array_type(g, u8_type, padding_bytes);7432 ZigType *padding_array = get_array_type(g, u8_type, padding_bytes);
7402 LLVMTypeRef union_element_types[] = {7433 LLVMTypeRef union_element_types[] = {
7403 get_llvm_type(g, most_aligned_union_member),7434 get_llvm_type(g, most_aligned_union_member->type_entry),
7404 get_llvm_type(g, padding_array),7435 get_llvm_type(g, padding_array),
7405 };7436 };
7406 union_type_ref = LLVMStructType(union_element_types, 2, false);7437 union_type_ref = LLVMStructType(union_element_types, 2, false);
...@@ -7416,7 +7447,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta...@@ -7416,7 +7447,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
7416 ZigLLVMDIType *union_di_type = ZigLLVMCreateDebugUnionType(g->dbuilder,7447 ZigLLVMDIType *union_di_type = ZigLLVMCreateDebugUnionType(g->dbuilder,
7417 ZigLLVMTypeToScope(union_type->llvm_di_type), "AnonUnion",7448 ZigLLVMTypeToScope(union_type->llvm_di_type), "AnonUnion",
7418 import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1),7449 import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1),
7419 most_aligned_union_member->size_in_bits, 8*most_aligned_union_member->abi_align,7450 most_aligned_union_member->type_entry->size_in_bits, 8*most_aligned_union_member->align,
7420 ZigLLVM_DIFlags_Zero, union_inner_di_types, gen_field_count, 0, "");7451 ZigLLVM_DIFlags_Zero, union_inner_di_types, gen_field_count, 0, "");
74217452
7422 uint64_t union_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, union_type->llvm_type,7453 uint64_t union_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, union_type->llvm_type,
...@@ -7427,8 +7458,8 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta...@@ -7427,8 +7458,8 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
7427 ZigLLVMDIType *union_member_di_type = ZigLLVMCreateDebugMemberType(g->dbuilder,7458 ZigLLVMDIType *union_member_di_type = ZigLLVMCreateDebugMemberType(g->dbuilder,
7428 ZigLLVMTypeToScope(union_type->llvm_di_type), "payload",7459 ZigLLVMTypeToScope(union_type->llvm_di_type), "payload",
7429 import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1),7460 import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1),
7430 most_aligned_union_member->size_in_bits,7461 most_aligned_union_member->type_entry->size_in_bits,
7431 8*most_aligned_union_member->abi_align,7462 8*most_aligned_union_member->align,
7432 union_offset_in_bits,7463 union_offset_in_bits,
7433 ZigLLVM_DIFlags_Zero, union_di_type);7464 ZigLLVM_DIFlags_Zero, union_di_type);
74347465
src/codegen.cpp+1-1
...@@ -6568,7 +6568,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c...@@ -6568,7 +6568,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c
6568 uint64_t pad_bytes = type_entry->data.unionation.union_abi_size - field_type_bytes;6568 uint64_t pad_bytes = type_entry->data.unionation.union_abi_size - field_type_bytes;
6569 LLVMValueRef correctly_typed_value = gen_const_val(g, payload_value, "");6569 LLVMValueRef correctly_typed_value = gen_const_val(g, payload_value, "");
6570 make_unnamed_struct = is_llvm_value_unnamed_type(g, payload_value->type, correctly_typed_value) ||6570 make_unnamed_struct = is_llvm_value_unnamed_type(g, payload_value->type, correctly_typed_value) ||
6571 payload_value->type != type_entry->data.unionation.most_aligned_union_member;6571 payload_value->type != type_entry->data.unionation.most_aligned_union_member->type_entry;
65726572
6573 {6573 {
6574 if (pad_bytes == 0) {6574 if (pad_bytes == 0) {