diff --git a/src/analyze.cpp b/src/analyze.cpp index 3318d4b9bb..fb677de0ee 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -5584,6 +5584,18 @@ ZigValue *get_the_one_possible_value(CodeGen *g, ZigType *type_entry) { ZigValue *result = create_const_vals(1); result->type = type_entry; result->special = ConstValSpecialStatic; + if (result->type->id == ZigTypeIdStruct) { + // The fields array cannot be left unpopulated + const ZigType *struct_type = result->type; + const size_t field_count = struct_type->data.structure.src_field_count; + result->data.x_struct.fields = alloc_const_vals_ptrs(field_count); + for (size_t i = 0; i < field_count; i += 1) { + TypeStructField *field = struct_type->data.structure.fields[i]; + ZigType *field_type = resolve_struct_field_type(g, field); + assert(field_type != nullptr); + result->data.x_struct.fields[i] = get_the_one_possible_value(g, field_type); + } + } g->one_possible_values.put(type_entry, result); return result; } diff --git a/src/ir.cpp b/src/ir.cpp index a5dee25645..bc16cef561 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -14018,7 +14018,8 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc case OnePossibleValueInvalid: return ira->codegen->invalid_instruction; case OnePossibleValueYes: - return ir_const(ira, source_instruction, child_type); + return ir_const_move(ira, source_instruction, + get_the_one_possible_value(ira->codegen, child_type)); case OnePossibleValueNo: break; } @@ -19226,7 +19227,8 @@ skip_resolve_peer_types: case OnePossibleValueInvalid: return ira->codegen->invalid_instruction; case OnePossibleValueYes: - return ir_const(ira, &phi_instruction->base, resolved_type); + return ir_const_move(ira, &phi_instruction->base, + get_the_one_possible_value(ira->codegen, resolved_type)); case OnePossibleValueNo: break; } @@ -19862,7 +19864,8 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction case OnePossibleValueInvalid: return ira->codegen->invalid_instruction; case OnePossibleValueYes: { - IrInstruction *elem = ir_const(ira, source_instr, field_type); + IrInstruction *elem = ir_const_move(ira, source_instr, + get_the_one_possible_value(ira->codegen, field_type)); return ir_get_ref(ira, source_instr, elem, false, false); } case OnePossibleValueNo: @@ -21933,7 +21936,8 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira, case OnePossibleValueInvalid: return ira->codegen->invalid_instruction; case OnePossibleValueYes: - return ir_const(ira, &instruction->base, container_type); + return ir_const_move(ira, &instruction->base, + get_the_one_possible_value(ira->codegen, container_type)); case OnePossibleValueNo: break; } diff --git a/test/stage1/behavior/pointers.zig b/test/stage1/behavior/pointers.zig index 265258025f..1dd07c8986 100644 --- a/test/stage1/behavior/pointers.zig +++ b/test/stage1/behavior/pointers.zig @@ -14,6 +14,22 @@ fn testDerefPtr() void { expect(x == 1235); } +const Foo1 = struct { + x: void, +}; + +test "dereference pointer again" { + testDerefPtrOneVal(); + comptime testDerefPtrOneVal(); +} + +fn testDerefPtrOneVal() void { + // Foo1 satisfies the OnePossibleValueYes criteria + const x = &Foo1{ .x = {} }; + const y = x.*; + expect(@TypeOf(y.x) == void); +} + test "pointer arithmetic" { var ptr: [*]const u8 = "abcd";