authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-02-28 15:49:19-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-02-28 15:49:19-05:00
logbee4007ec9a353b027654ccb4beeaf3d04dfa26f
tree2fcbf30fa1a5c7234788a29bea2b6b651ac3f725
parent68dbba212dd7393c90ab0e914dedeac975fa0224
signaturelock-open Commit is signed but in an unrecognized format.

fix crash with multiple comptime fn calls and...

...default initialized array to undefined closes #4578

2 files changed, 55 insertions(+), 9 deletions(-)

src/analyze.cpp+30-9
...@@ -5429,6 +5429,8 @@ static bool can_mutate_comptime_var_state(ZigValue *value) {...@@ -5429,6 +5429,8 @@ static bool can_mutate_comptime_var_state(ZigValue *value) {
5429 return value->data.x_ptr.mut == ConstPtrMutComptimeVar;5429 return value->data.x_ptr.mut == ConstPtrMutComptimeVar;
54305430
5431 case ZigTypeIdArray:5431 case ZigTypeIdArray:
5432 if (value->special == ConstValSpecialUndef)
5433 return false;
5432 if (value->type->data.array.len == 0)5434 if (value->type->data.array.len == 0)
5433 return false;5435 return false;
5434 switch (value->data.x_array.special) {5436 switch (value->data.x_array.special) {
...@@ -6701,8 +6703,16 @@ bool const_values_equal_ptr(ZigValue *a, ZigValue *b) {...@@ -6701,8 +6703,16 @@ bool const_values_equal_ptr(ZigValue *a, ZigValue *b) {
6701}6703}
67026704
6703static bool const_values_equal_array(CodeGen *g, ZigValue *a, ZigValue *b, size_t len) {6705static bool const_values_equal_array(CodeGen *g, ZigValue *a, ZigValue *b, size_t len) {
6704 assert(a->data.x_array.special != ConstArraySpecialUndef);6706 if (a->data.x_array.special == ConstArraySpecialUndef &&
6705 assert(b->data.x_array.special != ConstArraySpecialUndef);6707 b->data.x_array.special == ConstArraySpecialUndef)
6708 {
6709 return true;
6710 }
6711 if (a->data.x_array.special == ConstArraySpecialUndef ||
6712 b->data.x_array.special == ConstArraySpecialUndef)
6713 {
6714 return false;
6715 }
6706 if (a->data.x_array.special == ConstArraySpecialBuf &&6716 if (a->data.x_array.special == ConstArraySpecialBuf &&
6707 b->data.x_array.special == ConstArraySpecialBuf)6717 b->data.x_array.special == ConstArraySpecialBuf)
6708 {6718 {
...@@ -9398,13 +9408,24 @@ void copy_const_val(CodeGen *g, ZigValue *dest, ZigValue *src) {...@@ -9398,13 +9408,24 @@ void copy_const_val(CodeGen *g, ZigValue *dest, ZigValue *src) {
9398 dest->data.x_struct.fields[i]->parent.data.p_struct.field_index = i;9408 dest->data.x_struct.fields[i]->parent.data.p_struct.field_index = i;
9399 }9409 }
9400 } else if (dest->type->id == ZigTypeIdArray) {9410 } else if (dest->type->id == ZigTypeIdArray) {
9401 if (dest->data.x_array.special == ConstArraySpecialNone) {9411 switch (dest->data.x_array.special) {
9402 dest->data.x_array.data.s_none.elements = g->pass1_arena->allocate<ZigValue>(dest->type->data.array.len);9412 case ConstArraySpecialNone: {
9403 for (uint64_t i = 0; i < dest->type->data.array.len; i += 1) {9413 dest->data.x_array.data.s_none.elements = g->pass1_arena->allocate<ZigValue>(dest->type->data.array.len);
9404 copy_const_val(g, &dest->data.x_array.data.s_none.elements[i], &src->data.x_array.data.s_none.elements[i]);9414 for (uint64_t i = 0; i < dest->type->data.array.len; i += 1) {
9405 dest->data.x_array.data.s_none.elements[i].parent.id = ConstParentIdArray;9415 copy_const_val(g, &dest->data.x_array.data.s_none.elements[i], &src->data.x_array.data.s_none.elements[i]);
9406 dest->data.x_array.data.s_none.elements[i].parent.data.p_array.array_val = dest;9416 dest->data.x_array.data.s_none.elements[i].parent.id = ConstParentIdArray;
9407 dest->data.x_array.data.s_none.elements[i].parent.data.p_array.elem_index = i;9417 dest->data.x_array.data.s_none.elements[i].parent.data.p_array.array_val = dest;
9418 dest->data.x_array.data.s_none.elements[i].parent.data.p_array.elem_index = i;
9419 }
9420 break;
9421 }
9422 case ConstArraySpecialUndef: {
9423 // Nothing to copy; the above memcpy did everything we needed.
9424 break;
9425 }
9426 case ConstArraySpecialBuf: {
9427 dest->data.x_array.data.s_buf = buf_create_from_buf(src->data.x_array.data.s_buf);
9428 break;
9408 }9429 }
9409 }9430 }
9410 } else if (type_has_optional_repr(dest->type) && dest->data.x_optional != nullptr) {9431 } else if (type_has_optional_repr(dest->type) && dest->data.x_optional != nullptr) {
test/stage1/behavior/eval.zig+25
...@@ -807,3 +807,28 @@ test "return 0 from function that has u0 return type" {...@@ -807,3 +807,28 @@ test "return 0 from function that has u0 return type" {
807 }807 }
808 }808 }
809}809}
810
811test "two comptime calls with array default initialized to undefined" {
812 const S = struct {
813 const CrossTarget = struct {
814 dynamic_linker: DynamicLinker = DynamicLinker{},
815
816 pub fn parse() void {
817 var result: CrossTarget = .{ };
818 result.getCpuArch();
819 }
820
821 pub fn getCpuArch(self: CrossTarget) void { }
822 };
823
824 const DynamicLinker = struct {
825 buffer: [255]u8 = undefined,
826 };
827
828 };
829
830 comptime {
831 S.CrossTarget.parse();
832 S.CrossTarget.parse();
833 }
834}