authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-01-29 23:35:34-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-01-29 23:35:34-05:00
logd2b94afaf2383bbcb03ab201e544aa830c082e99
tree4b79c49847896a7962ba7e151121f4a7ec6fa584
parent3caf6bacdcc797167e5db1b5545aad8e464cf311

fix compile time initialization of array with undefined


5 files changed, 60 insertions(+), 1 deletions(-)

src/all_types.hpp+1
...@@ -80,6 +80,7 @@ struct ConstArrayValue {...@@ -80,6 +80,7 @@ struct ConstArrayValue {
80 ConstExprValue *elements;80 ConstExprValue *elements;
81 // This will be the same as `len` from the type, but we duplicate the information81 // This will be the same as `len` from the type, but we duplicate the information
82 // in the constant value so that pointers pointing to arrays can see this size.82 // in the constant value so that pointers pointing to arrays can see this size.
83 // TODO now that ConstExprValue has the type field we can use that instead of this.
83 size_t size;84 size_t size;
84 // If the data for this array is supposed to be contained in a different constant85 // If the data for this array is supposed to be contained in a different constant
85 // value, we link to the parent here. This way getting a pointer to this constant86 // value, we link to the parent here. This way getting a pointer to this constant
src/analyze.cpp+21
...@@ -3190,6 +3190,27 @@ ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_...@@ -3190,6 +3190,27 @@ ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_
3190}3190}
31913191
31923192
3193void init_const_undefined(ConstExprValue *const_val) {
3194 TypeTableEntry *canon_wanted_type = get_underlying_type(const_val->type);
3195 if (canon_wanted_type->id == TypeTableEntryIdArray) {
3196 const_val->special = ConstValSpecialStatic;
3197 size_t elem_count = canon_wanted_type->data.array.len;
3198 const_val->data.x_array.elements = allocate<ConstExprValue>(elem_count);
3199 const_val->data.x_array.size = elem_count;
3200 for (size_t i = 0; i < elem_count; i += 1) {
3201 ConstExprValue *element_val = &const_val->data.x_array.elements[i];
3202 element_val->type = canon_wanted_type->data.array.child_type;
3203 init_const_undefined(element_val);
3204 if (get_underlying_type(element_val->type)->id == TypeTableEntryIdArray) {
3205 element_val->data.x_array.parent_array = const_val;
3206 element_val->data.x_array.parent_array_index = i;
3207 }
3208 }
3209 } else {
3210 const_val->special = ConstValSpecialUndef;
3211 }
3212}
3213
3193void ensure_complete_type(CodeGen *g, TypeTableEntry *type_entry) {3214void ensure_complete_type(CodeGen *g, TypeTableEntry *type_entry) {
3194 if (type_entry->id == TypeTableEntryIdStruct) {3215 if (type_entry->id == TypeTableEntryIdStruct) {
3195 if (!type_entry->data.structure.complete)3216 if (!type_entry->data.structure.complete)
src/analyze.hpp+2
...@@ -136,4 +136,6 @@ ConstExprValue *create_const_slice(CodeGen *g, ConstExprValue *array_val, size_t...@@ -136,4 +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);
140
139#endif141#endif
src/ir.cpp+10-1
...@@ -6347,6 +6347,15 @@ static IrInstruction *ir_analyze_enum_to_int(IrAnalyze *ira, IrInstruction *sour...@@ -6347,6 +6347,15 @@ static IrInstruction *ir_analyze_enum_to_int(IrAnalyze *ira, IrInstruction *sour
6347 return result;6347 return result;
6348}6348}
63496349
6350static IrInstruction *ir_analyze_undefined_to_anything(IrAnalyze *ira, IrInstruction *source_instr,
6351 IrInstruction *target, TypeTableEntry *wanted_type)
6352{
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);
6355 init_const_undefined(&result->value);
6356 return result;
6357}
6358
6350static IrInstruction *ir_analyze_widen_or_shorten(IrAnalyze *ira, IrInstruction *source_instr,6359static IrInstruction *ir_analyze_widen_or_shorten(IrAnalyze *ira, IrInstruction *source_instr,
6351 IrInstruction *target, TypeTableEntry *wanted_type)6360 IrInstruction *target, TypeTableEntry *wanted_type)
6352{6361{
...@@ -6671,7 +6680,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -6671,7 +6680,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
66716680
6672 // explicit cast from undefined to anything6681 // explicit cast from undefined to anything
6673 if (actual_type->id == TypeTableEntryIdUndefLit) {6682 if (actual_type->id == TypeTableEntryIdUndefLit) {
6674 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false);6683 return ir_analyze_undefined_to_anything(ira, source_instr, value, wanted_type);
6675 }6684 }
66766685
6677 // explicit cast from something to const pointer of it6686 // explicit cast from something to const pointer of it
test/cases/eval.zig+26
...@@ -252,3 +252,29 @@ fn comptimeIterateOverFnPtrList() {...@@ -252,3 +252,29 @@ 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}