authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-02-02 14:55:01-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-02-02 14:55:01-05:00
log2b88441295d39d3e988c0771b6ad64531948ff0a
tree2b812b9985642b79eeb56e1018a4266cfa916f7a
parentb78c91951a1db34c615a011e0444608285f1a74c

fix behavior when initializing struct with undefined


6 files changed, 68 insertions(+), 30 deletions(-)

src/analyze.cpp+16-2
...@@ -275,6 +275,8 @@ TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool...@@ -275,6 +275,8 @@ TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool
275 if (*parent_pointer) {275 if (*parent_pointer) {
276 return *parent_pointer;276 return *parent_pointer;
277 } else {277 } else {
278 type_ensure_zero_bits_known(g, child_type);
279
278 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdPointer);280 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdPointer);
279281
280 const char *const_str = is_const ? "const " : "";282 const char *const_str = is_const ? "const " : "";
...@@ -3190,7 +3192,7 @@ ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_...@@ -3190,7 +3192,7 @@ ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_
3190}3192}
31913193
31923194
3193void init_const_undefined(ConstExprValue *const_val) {3195void init_const_undefined(CodeGen *g, ConstExprValue *const_val) {
3194 TypeTableEntry *canon_wanted_type = get_underlying_type(const_val->type);3196 TypeTableEntry *canon_wanted_type = get_underlying_type(const_val->type);
3195 if (canon_wanted_type->id == TypeTableEntryIdArray) {3197 if (canon_wanted_type->id == TypeTableEntryIdArray) {
3196 const_val->special = ConstValSpecialStatic;3198 const_val->special = ConstValSpecialStatic;
...@@ -3200,12 +3202,24 @@ void init_const_undefined(ConstExprValue *const_val) {...@@ -3200,12 +3202,24 @@ void init_const_undefined(ConstExprValue *const_val) {
3200 for (size_t i = 0; i < elem_count; i += 1) {3202 for (size_t i = 0; i < elem_count; i += 1) {
3201 ConstExprValue *element_val = &const_val->data.x_array.elements[i];3203 ConstExprValue *element_val = &const_val->data.x_array.elements[i];
3202 element_val->type = canon_wanted_type->data.array.child_type;3204 element_val->type = canon_wanted_type->data.array.child_type;
3203 init_const_undefined(element_val);3205 init_const_undefined(g, element_val);
3204 if (get_underlying_type(element_val->type)->id == TypeTableEntryIdArray) {3206 if (get_underlying_type(element_val->type)->id == TypeTableEntryIdArray) {
3205 element_val->data.x_array.parent_array = const_val;3207 element_val->data.x_array.parent_array = const_val;
3206 element_val->data.x_array.parent_array_index = i;3208 element_val->data.x_array.parent_array_index = i;
3207 }3209 }
3208 }3210 }
3211 } else if (canon_wanted_type->id == TypeTableEntryIdStruct) {
3212 ensure_complete_type(g, canon_wanted_type);
3213
3214 const_val->special = ConstValSpecialStatic;
3215 size_t field_count = canon_wanted_type->data.structure.src_field_count;
3216 const_val->data.x_struct.fields = allocate<ConstExprValue>(field_count);
3217 for (size_t i = 0; i < field_count; i += 1) {
3218 ConstExprValue *field_val = &const_val->data.x_struct.fields[i];
3219 field_val->type = canon_wanted_type->data.structure.fields[i].type_entry;
3220 assert(field_val->type);
3221 init_const_undefined(g, field_val);
3222 }
3209 } else {3223 } else {
3210 const_val->special = ConstValSpecialUndef;3224 const_val->special = ConstValSpecialUndef;
3211 }3225 }
src/analyze.hpp+1-1
...@@ -136,6 +136,6 @@ ConstExprValue *create_const_slice(CodeGen *g, ConstExprValue *array_val, size_t...@@ -136,6 +136,6 @@ ConstExprValue *create_const_slice(CodeGen *g, ConstExprValue *array_val, size_t
136void init_const_arg_tuple(CodeGen *g, ConstExprValue *const_val, size_t arg_index_start, size_t arg_index_end);136void init_const_arg_tuple(CodeGen *g, ConstExprValue *const_val, size_t arg_index_start, size_t arg_index_end);
137ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_t arg_index_end);137ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_t arg_index_end);
138138
139void init_const_undefined(ConstExprValue *const_val);139void init_const_undefined(CodeGen *g, ConstExprValue *const_val);
140140
141#endif141#endif
src/ir.cpp+1-1
...@@ -6352,7 +6352,7 @@ static IrInstruction *ir_analyze_undefined_to_anything(IrAnalyze *ira, IrInstruc...@@ -6352,7 +6352,7 @@ static IrInstruction *ir_analyze_undefined_to_anything(IrAnalyze *ira, IrInstruc
6352{6352{
6353 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope,6353 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope,
6354 source_instr->source_node, wanted_type, target->value.depends_on_compile_var);6354 source_instr->source_node, wanted_type, target->value.depends_on_compile_var);
6355 init_const_undefined(&result->value);6355 init_const_undefined(ira->codegen, &result->value);
6356 return result;6356 return result;
6357}6357}
63586358
test/cases/eval.zig-26
...@@ -252,29 +252,3 @@ fn comptimeIterateOverFnPtrList() {...@@ -252,29 +252,3 @@ fn comptimeIterateOverFnPtrList() {
252 assert(performFn('o', 0) == 1);252 assert(performFn('o', 0) == 1);
253 assert(performFn('w', 99) == 99);253 assert(performFn('w', 99) == 99);
254}254}
255
256
257fn initStaticArray() -> [10]i32 {
258 var array: [10]i32 = undefined;
259 array[0] = 1;
260 array[4] = 2;
261 array[7] = 3;
262 array[9] = 4;
263 return array;
264}
265const static_array = initStaticArray();
266fn initStaticArrayToUndefined() {
267 @setFnTest(this);
268
269 assert(static_array[0] == 1);
270 assert(static_array[4] == 2);
271 assert(static_array[7] == 3);
272 assert(static_array[9] == 4);
273
274 comptime {
275 assert(static_array[0] == 1);
276 assert(static_array[4] == 2);
277 assert(static_array[7] == 3);
278 assert(static_array[9] == 4);
279 }
280}
test/cases/undefined.zig created+49
...@@ -0,0 +1,49 @@
1const assert = @import("std").debug.assert;
2
3fn initStaticArray() -> [10]i32 {
4 var array: [10]i32 = undefined;
5 array[0] = 1;
6 array[4] = 2;
7 array[7] = 3;
8 array[9] = 4;
9 return array;
10}
11const static_array = initStaticArray();
12fn initStaticArrayToUndefined() {
13 @setFnTest(this);
14
15 assert(static_array[0] == 1);
16 assert(static_array[4] == 2);
17 assert(static_array[7] == 3);
18 assert(static_array[9] == 4);
19
20 comptime {
21 assert(static_array[0] == 1);
22 assert(static_array[4] == 2);
23 assert(static_array[7] == 3);
24 assert(static_array[9] == 4);
25 }
26}
27
28const Foo = struct {
29 x: i32,
30};
31
32fn setFooX(foo: &Foo) {
33 foo.x = 2;
34}
35
36fn assignUndefinedToStruct() {
37 @setFnTest(this);
38
39 comptime {
40 var foo: Foo = undefined;
41 setFooX(&foo);
42 assert(foo.x == 2);
43 }
44 {
45 var foo: Foo = undefined;
46 setFooX(&foo);
47 assert(foo.x == 2);
48 }
49}
test/self_hosted.zig+1
...@@ -28,5 +28,6 @@ const test_switch = @import("cases/switch.zig");...@@ -28,5 +28,6 @@ const test_switch = @import("cases/switch.zig");
28const test_switch_prong_err_enum = @import("cases/switch_prong_err_enum.zig");28const test_switch_prong_err_enum = @import("cases/switch_prong_err_enum.zig");
29const test_switch_prong_implicit_cast = @import("cases/switch_prong_implicit_cast.zig");29const test_switch_prong_implicit_cast = @import("cases/switch_prong_implicit_cast.zig");
30const test_this = @import("cases/this.zig");30const test_this = @import("cases/this.zig");
31const test_undefined = @import("cases/undefined.zig");
31const test_var_args = @import("cases/var_args.zig");32const test_var_args = @import("cases/var_args.zig");
32const test_while = @import("cases/while.zig");33const test_while = @import("cases/while.zig");