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) {...@@ -5584,6 +5584,18 @@ ZigValue *get_the_one_possible_value(CodeGen *g, ZigType *type_entry) {
5584 ZigValue *result = create_const_vals(1);5584 ZigValue *result = create_const_vals(1);
5585 result->type = type_entry;5585 result->type = type_entry;
5586 result->special = ConstValSpecialStatic;5586 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 }
5587 g->one_possible_values.put(type_entry, result);5599 g->one_possible_values.put(type_entry, result);
5588 return result;5600 return result;
5589}5601}
src/ir.cpp+8-4
...@@ -14018,7 +14018,8 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc...@@ -14018,7 +14018,8 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc
14018 case OnePossibleValueInvalid:14018 case OnePossibleValueInvalid:
14019 return ira->codegen->invalid_instruction;14019 return ira->codegen->invalid_instruction;
14020 case OnePossibleValueYes:14020 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));
14022 case OnePossibleValueNo:14023 case OnePossibleValueNo:
14023 break;14024 break;
14024 }14025 }
...@@ -19226,7 +19227,8 @@ skip_resolve_peer_types:...@@ -19226,7 +19227,8 @@ skip_resolve_peer_types:
19226 case OnePossibleValueInvalid:19227 case OnePossibleValueInvalid:
19227 return ira->codegen->invalid_instruction;19228 return ira->codegen->invalid_instruction;
19228 case OnePossibleValueYes:19229 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));
19230 case OnePossibleValueNo:19232 case OnePossibleValueNo:
19231 break;19233 break;
19232 }19234 }
...@@ -19862,7 +19864,8 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction...@@ -19862,7 +19864,8 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction
19862 case OnePossibleValueInvalid:19864 case OnePossibleValueInvalid:
19863 return ira->codegen->invalid_instruction;19865 return ira->codegen->invalid_instruction;
19864 case OnePossibleValueYes: {19866 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));
19866 return ir_get_ref(ira, source_instr, elem, false, false);19869 return ir_get_ref(ira, source_instr, elem, false, false);
19867 }19870 }
19868 case OnePossibleValueNo:19871 case OnePossibleValueNo:
...@@ -21933,7 +21936,8 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira,...@@ -21933,7 +21936,8 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira,
21933 case OnePossibleValueInvalid:21936 case OnePossibleValueInvalid:
21934 return ira->codegen->invalid_instruction;21937 return ira->codegen->invalid_instruction;
21935 case OnePossibleValueYes:21938 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));
21937 case OnePossibleValueNo:21941 case OnePossibleValueNo:
21938 break;21942 break;
21939 }21943 }
test/stage1/behavior/pointers.zig+16
...@@ -14,6 +14,22 @@ fn testDerefPtr() void {...@@ -14,6 +14,22 @@ fn testDerefPtr() void {
14 expect(x == 1235);14 expect(x == 1235);
15}15}
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
17test "pointer arithmetic" {33test "pointer arithmetic" {
18 var ptr: [*]const u8 = "abcd";34 var ptr: [*]const u8 = "abcd";
1935