Commit bee4007ec9
Changed files (2)
src
test
stage1
behavior
src/analyze.cpp
@@ -5429,6 +5429,8 @@ static bool can_mutate_comptime_var_state(ZigValue *value) {
return value->data.x_ptr.mut == ConstPtrMutComptimeVar;
case ZigTypeIdArray:
+ if (value->special == ConstValSpecialUndef)
+ return false;
if (value->type->data.array.len == 0)
return false;
switch (value->data.x_array.special) {
@@ -6701,8 +6703,16 @@ bool const_values_equal_ptr(ZigValue *a, ZigValue *b) {
}
static bool const_values_equal_array(CodeGen *g, ZigValue *a, ZigValue *b, size_t len) {
- assert(a->data.x_array.special != ConstArraySpecialUndef);
- assert(b->data.x_array.special != ConstArraySpecialUndef);
+ if (a->data.x_array.special == ConstArraySpecialUndef &&
+ b->data.x_array.special == ConstArraySpecialUndef)
+ {
+ return true;
+ }
+ if (a->data.x_array.special == ConstArraySpecialUndef ||
+ b->data.x_array.special == ConstArraySpecialUndef)
+ {
+ return false;
+ }
if (a->data.x_array.special == ConstArraySpecialBuf &&
b->data.x_array.special == ConstArraySpecialBuf)
{
@@ -9398,13 +9408,24 @@ void copy_const_val(CodeGen *g, ZigValue *dest, ZigValue *src) {
dest->data.x_struct.fields[i]->parent.data.p_struct.field_index = i;
}
} else if (dest->type->id == ZigTypeIdArray) {
- if (dest->data.x_array.special == ConstArraySpecialNone) {
- dest->data.x_array.data.s_none.elements = g->pass1_arena->allocate<ZigValue>(dest->type->data.array.len);
- for (uint64_t i = 0; i < dest->type->data.array.len; i += 1) {
- copy_const_val(g, &dest->data.x_array.data.s_none.elements[i], &src->data.x_array.data.s_none.elements[i]);
- dest->data.x_array.data.s_none.elements[i].parent.id = ConstParentIdArray;
- dest->data.x_array.data.s_none.elements[i].parent.data.p_array.array_val = dest;
- dest->data.x_array.data.s_none.elements[i].parent.data.p_array.elem_index = i;
+ switch (dest->data.x_array.special) {
+ case ConstArraySpecialNone: {
+ dest->data.x_array.data.s_none.elements = g->pass1_arena->allocate<ZigValue>(dest->type->data.array.len);
+ for (uint64_t i = 0; i < dest->type->data.array.len; i += 1) {
+ copy_const_val(g, &dest->data.x_array.data.s_none.elements[i], &src->data.x_array.data.s_none.elements[i]);
+ dest->data.x_array.data.s_none.elements[i].parent.id = ConstParentIdArray;
+ dest->data.x_array.data.s_none.elements[i].parent.data.p_array.array_val = dest;
+ dest->data.x_array.data.s_none.elements[i].parent.data.p_array.elem_index = i;
+ }
+ break;
+ }
+ case ConstArraySpecialUndef: {
+ // Nothing to copy; the above memcpy did everything we needed.
+ break;
+ }
+ case ConstArraySpecialBuf: {
+ dest->data.x_array.data.s_buf = buf_create_from_buf(src->data.x_array.data.s_buf);
+ break;
}
}
} else if (type_has_optional_repr(dest->type) && dest->data.x_optional != nullptr) {
test/stage1/behavior/eval.zig
@@ -807,3 +807,28 @@ test "return 0 from function that has u0 return type" {
}
}
}
+
+test "two comptime calls with array default initialized to undefined" {
+ const S = struct {
+ const CrossTarget = struct {
+ dynamic_linker: DynamicLinker = DynamicLinker{},
+
+ pub fn parse() void {
+ var result: CrossTarget = .{ };
+ result.getCpuArch();
+ }
+
+ pub fn getCpuArch(self: CrossTarget) void { }
+ };
+
+ const DynamicLinker = struct {
+ buffer: [255]u8 = undefined,
+ };
+
+ };
+
+ comptime {
+ S.CrossTarget.parse();
+ S.CrossTarget.parse();
+ }
+}