aboutsummaryrefslogtreecommitdiff
path: root/src/stage1/analyze.cpp
diff options
context:
space:
mode:
authorLemonBoy <thatlemon@gmail.com>2020-10-21 15:35:40 +0200
committerAndrew Kelley <andrew@ziglang.org>2020-10-21 22:42:03 -0400
commit44f8e6a534bd2977c741afdbf5ba9df49bde0fd9 (patch)
tree2d7274179977704d5bd24074b6f9306518da14de /src/stage1/analyze.cpp
parent52879b50d9fe221c46e62e11c6815da64c70638e (diff)
downloadzig-44f8e6a534bd2977c741afdbf5ba9df49bde0fd9.tar.gz
zig-44f8e6a534bd2977c741afdbf5ba9df49bde0fd9.zip
stage1: Fix edge case in Union ZigValue generation
Unions that passed the one_possible_value check were incorrectly generated, none of their internal fields were initialized. Fixes #6758
Diffstat (limited to 'src/stage1/analyze.cpp')
-rw-r--r--src/stage1/analyze.cpp16
1 files changed, 15 insertions, 1 deletions
diff --git a/src/stage1/analyze.cpp b/src/stage1/analyze.cpp
index fb1360727c..04c064efe3 100644
--- a/src/stage1/analyze.cpp
+++ b/src/stage1/analyze.cpp
@@ -5973,7 +5973,8 @@ ZigValue *get_the_one_possible_value(CodeGen *g, ZigType *type_entry) {
}
ZigType *field_type = resolve_struct_field_type(g, field);
assert(field_type != nullptr);
- result->data.x_struct.fields[i] = get_the_one_possible_value(g, field_type);
+ copy_const_val(g, result->data.x_struct.fields[i],
+ get_the_one_possible_value(g, field_type));
}
} else if (result->type->id == ZigTypeIdArray) {
// The elements array cannot be left unpopulated
@@ -5986,7 +5987,20 @@ ZigValue *get_the_one_possible_value(CodeGen *g, ZigType *type_entry) {
ZigValue *elem_val = &result->data.x_array.data.s_none.elements[i];
copy_const_val(g, elem_val, get_the_one_possible_value(g, elem_type));
}
+ } else if (result->type->id == ZigTypeIdUnion) {
+ // The payload/tag fields cannot be left unpopulated
+ ZigType *union_type = result->type;
+ assert(union_type->data.unionation.src_field_count == 1);
+ TypeUnionField *only_field = &union_type->data.unionation.fields[0];
+ ZigType *field_type = resolve_union_field_type(g, only_field);
+ assert(field_type);
+ bigint_init_unsigned(&result->data.x_union.tag, 0);
+ result->data.x_union.payload = g->pass1_arena->create<ZigValue>();
+ copy_const_val(g, result->data.x_union.payload,
+ get_the_one_possible_value(g, field_type));
} else if (result->type->id == ZigTypeIdPointer) {
+ // Make sure nobody can modify the constant value
+ result->data.x_ptr.mut = ConstPtrMutComptimeConst;
result->data.x_ptr.special = ConstPtrSpecialRef;
result->data.x_ptr.data.ref.pointee = get_the_one_possible_value(g, result->type->data.pointer.child_type);
}