| author | |
| committer | |
| log | d2b94afaf2383bbcb03ab201e544aa830c082e99 |
| tree | 4b79c49847896a7962ba7e151121f4a7ec6fa584 |
| parent | 3caf6bacdcc797167e5db1b5545aad8e464cf311 |
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 information | 81 | // 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 constant | 85 | // 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 constant | 86 | // 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 | } |
| 3191 | 3191 | ||
| 3192 | 3192 | ||
| 3193 | void 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 | |||
| 3193 | void ensure_complete_type(CodeGen *g, TypeTableEntry *type_entry) { | 3214 | void 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 |
| 136 | void init_const_arg_tuple(CodeGen *g, ConstExprValue *const_val, size_t arg_index_start, size_t arg_index_end); | 136 | void init_const_arg_tuple(CodeGen *g, ConstExprValue *const_val, size_t arg_index_start, size_t arg_index_end); |
| 137 | ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_t arg_index_end); | 137 | ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_t arg_index_end); |
| 138 | 138 | ||
| 139 | void init_const_undefined(ConstExprValue *const_val); | ||
| 140 | |||
| 139 | #endif | 141 | #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 | } |
| 6349 | 6349 | ||
| 6350 | static 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 | |||
| 6350 | static IrInstruction *ir_analyze_widen_or_shorten(IrAnalyze *ira, IrInstruction *source_instr, | 6359 | static 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 |
| 6671 | 6680 | ||
| 6672 | // explicit cast from undefined to anything | 6681 | // 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 | } |
| 6676 | 6685 | ||
| 6677 | // explicit cast from something to const pointer of it | 6686 | // 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 | |||
| 257 | fn 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 | } | ||
| 265 | const static_array = initStaticArray(); | ||
| 266 | fn 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 | } |