authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2019-12-17 00:31:32+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-12-17 15:45:22-05:00
logd8499f7abe43ec641027eb7f94b41906c9bf5cca
tree913014c0990e942c569fad7e67b2f9a701e1be09
parentf389e5e61fcbc92423c16ccd2d0c79878d1589e4

Make sure the fields array is always non-null

Fixes #3497

3 files changed, 36 insertions(+), 4 deletions(-)

src/analyze.cpp+12
......@@ -5584,6 +5584,18 @@ ZigValue *get_the_one_possible_value(CodeGen *g, ZigType *type_entry) {
55845584 ZigValue *result = create_const_vals(1);
55855585 result->type = type_entry;
55865586 result->special = ConstValSpecialStatic;
5587 if (result->type->id == ZigTypeIdStruct) {
5588 // The fields array cannot be left unpopulated
5589 const ZigType *struct_type = result->type;
5590 const size_t field_count = struct_type->data.structure.src_field_count;
5591 result->data.x_struct.fields = alloc_const_vals_ptrs(field_count);
5592 for (size_t i = 0; i < field_count; i += 1) {
5593 TypeStructField *field = struct_type->data.structure.fields[i];
5594 ZigType *field_type = resolve_struct_field_type(g, field);
5595 assert(field_type != nullptr);
5596 result->data.x_struct.fields[i] = get_the_one_possible_value(g, field_type);
5597 }
5598 }
55875599 g->one_possible_values.put(type_entry, result);
55885600 return result;
55895601}
src/ir.cpp+8-4
......@@ -14018,7 +14018,8 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc
1401814018 case OnePossibleValueInvalid:
1401914019 return ira->codegen->invalid_instruction;
1402014020 case OnePossibleValueYes:
14021 return ir_const(ira, source_instruction, child_type);
14021 return ir_const_move(ira, source_instruction,
14022 get_the_one_possible_value(ira->codegen, child_type));
1402214023 case OnePossibleValueNo:
1402314024 break;
1402414025 }
......@@ -19226,7 +19227,8 @@ skip_resolve_peer_types:
1922619227 case OnePossibleValueInvalid:
1922719228 return ira->codegen->invalid_instruction;
1922819229 case OnePossibleValueYes:
19229 return ir_const(ira, &phi_instruction->base, resolved_type);
19230 return ir_const_move(ira, &phi_instruction->base,
19231 get_the_one_possible_value(ira->codegen, resolved_type));
1923019232 case OnePossibleValueNo:
1923119233 break;
1923219234 }
......@@ -19862,7 +19864,8 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction
1986219864 case OnePossibleValueInvalid:
1986319865 return ira->codegen->invalid_instruction;
1986419866 case OnePossibleValueYes: {
19865 IrInstruction *elem = ir_const(ira, source_instr, field_type);
19867 IrInstruction *elem = ir_const_move(ira, source_instr,
19868 get_the_one_possible_value(ira->codegen, field_type));
1986619869 return ir_get_ref(ira, source_instr, elem, false, false);
1986719870 }
1986819871 case OnePossibleValueNo:
......@@ -21933,7 +21936,8 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira,
2193321936 case OnePossibleValueInvalid:
2193421937 return ira->codegen->invalid_instruction;
2193521938 case OnePossibleValueYes:
21936 return ir_const(ira, &instruction->base, container_type);
21939 return ir_const_move(ira, &instruction->base,
21940 get_the_one_possible_value(ira->codegen, container_type));
2193721941 case OnePossibleValueNo:
2193821942 break;
2193921943 }
test/stage1/behavior/pointers.zig+16
......@@ -14,6 +14,22 @@ fn testDerefPtr() void {
1414 expect(x == 1235);
1515}
1616
17const Foo1 = struct {
18 x: void,
19};
20
21test "dereference pointer again" {
22 testDerefPtrOneVal();
23 comptime testDerefPtrOneVal();
24}
25
26fn testDerefPtrOneVal() void {
27 // Foo1 satisfies the OnePossibleValueYes criteria
28 const x = &Foo1{ .x = {} };
29 const y = x.*;
30 expect(@TypeOf(y.x) == void);
31}
32
1733test "pointer arithmetic" {
1834 var ptr: [*]const u8 = "abcd";
1935