| author | |
| committer | |
| log | 2b88441295d39d3e988c0771b6ad64531948ff0a |
| tree | 2b812b9985642b79eeb56e1018a4266cfa916f7a |
| parent | b78c91951a1db34c615a011e0444608285f1a74c |
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); |
| 279 | 281 | ||
| 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 | } |
| 3191 | 3193 | ||
| 3192 | 3194 | ||
| 3193 | void init_const_undefined(ConstExprValue *const_val) { | 3195 | void 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 |
| 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); | 139 | void init_const_undefined(CodeGen *g, ConstExprValue *const_val); |
| 140 | 140 | ||
| 141 | #endif | 141 | #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 | } |
| 6358 | 6358 |
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 | |||
| 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 | } |
test/cases/undefined.zig created+49| ... | @@ -0,0 +1,49 @@ | ||
| 1 | const assert = @import("std").debug.assert; | ||
| 2 | |||
| 3 | fn 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 | } | ||
| 11 | const static_array = initStaticArray(); | ||
| 12 | fn 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 | |||
| 28 | const Foo = struct { | ||
| 29 | x: i32, | ||
| 30 | }; | ||
| 31 | |||
| 32 | fn setFooX(foo: &Foo) { | ||
| 33 | foo.x = 2; | ||
| 34 | } | ||
| 35 | |||
| 36 | fn 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"); |
| 28 | const test_switch_prong_err_enum = @import("cases/switch_prong_err_enum.zig"); | 28 | const test_switch_prong_err_enum = @import("cases/switch_prong_err_enum.zig"); |
| 29 | const test_switch_prong_implicit_cast = @import("cases/switch_prong_implicit_cast.zig"); | 29 | const test_switch_prong_implicit_cast = @import("cases/switch_prong_implicit_cast.zig"); |
| 30 | const test_this = @import("cases/this.zig"); | 30 | const test_this = @import("cases/this.zig"); |
| 31 | const test_undefined = @import("cases/undefined.zig"); | ||
| 31 | const test_var_args = @import("cases/var_args.zig"); | 32 | const test_var_args = @import("cases/var_args.zig"); |
| 32 | const test_while = @import("cases/while.zig"); | 33 | const test_while = @import("cases/while.zig"); |