authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-11-29 12:39:15+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-11-29 11:39:35-07:00
loga7c2cfe16d4267ea4e4719568c12a7a950374b0c
tree357b33ce8bf2502895739e8c4e45e2e0c9bc24a8
parent0a4a99ec8760b10b209fe886dbea6f15413d52d2

stage1: Fix typeInfo generation for arrays w/o sentinel

ZigTypeIdOptional types have a different way of specifying their payload value depending on whether the child type is a pointer or not (plus some other special cases). Fixes #7251

2 files changed, 25 insertions(+), 13 deletions(-)

src/stage1/ir.cpp+10-6
...@@ -25062,12 +25062,12 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInst* source_instr, ZigVa...@@ -25062,12 +25062,12 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInst* source_instr, ZigVa
25062 0, 0, 0, false);25062 0, 0, 0, false);
25063 fn_decl_fields[5]->type = get_optional_type(ira->codegen, get_slice_type(ira->codegen, u8_ptr));25063 fn_decl_fields[5]->type = get_optional_type(ira->codegen, get_slice_type(ira->codegen, u8_ptr));
25064 if (fn_node->is_extern && fn_node->lib_name != nullptr && buf_len(fn_node->lib_name) > 0) {25064 if (fn_node->is_extern && fn_node->lib_name != nullptr && buf_len(fn_node->lib_name) > 0) {
25065 fn_decl_fields[5]->data.x_optional = ira->codegen->pass1_arena->create<ZigValue>();25065 ZigValue *slice_val = ira->codegen->pass1_arena->create<ZigValue>();
25066 ZigValue *lib_name = create_const_str_lit(ira->codegen, fn_node->lib_name)->data.x_ptr.data.ref.pointee;25066 ZigValue *lib_name = create_const_str_lit(ira->codegen, fn_node->lib_name)->data.x_ptr.data.ref.pointee;
25067 init_const_slice(ira->codegen, fn_decl_fields[5]->data.x_optional, lib_name, 0,25067 init_const_slice(ira->codegen, slice_val, lib_name, 0, buf_len(fn_node->lib_name), true);
25068 buf_len(fn_node->lib_name), true);25068 set_optional_payload(fn_decl_fields[5], slice_val);
25069 } else {25069 } else {
25070 fn_decl_fields[5]->data.x_optional = nullptr;25070 set_optional_payload(fn_decl_fields[5], nullptr);
25071 }25071 }
25072 // return_type: type25072 // return_type: type
25073 ensure_field_index(fn_decl_val->type, "return_type", 6);25073 ensure_field_index(fn_decl_val->type, "return_type", 6);
...@@ -25347,8 +25347,12 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy...@@ -25347,8 +25347,12 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
25347 fields[1]->data.x_type = type_entry->data.array.child_type;25347 fields[1]->data.x_type = type_entry->data.array.child_type;
25348 // sentinel: anytype25348 // sentinel: anytype
25349 fields[2]->special = ConstValSpecialStatic;25349 fields[2]->special = ConstValSpecialStatic;
25350 fields[2]->type = get_optional_type(ira->codegen, type_entry->data.array.child_type);25350 if (type_entry->data.array.child_type != nullptr) {
25351 fields[2]->data.x_optional = type_entry->data.array.sentinel;25351 fields[2]->type = get_optional_type(ira->codegen, type_entry->data.array.child_type);
25352 set_optional_payload(fields[2], type_entry->data.array.sentinel);
25353 } else {
25354 fields[2]->type = ira->codegen->builtin_types.entry_null;
25355 }
25352 break;25356 break;
25353 }25357 }
25354 case ZigTypeIdVector: {25358 case ZigTypeIdVector: {
test/stage1/behavior/type_info.zig+15-7
...@@ -82,9 +82,6 @@ fn testNullTerminatedPtr() void {...@@ -82,9 +82,6 @@ fn testNullTerminatedPtr() void {
82 expect(ptr_info.Pointer.sentinel.? == 0);82 expect(ptr_info.Pointer.sentinel.? == 0);
8383
84 expect(@typeInfo([:0]u8).Pointer.sentinel != null);84 expect(@typeInfo([:0]u8).Pointer.sentinel != null);
85 expect(@typeInfo([10:0]u8).Array.sentinel != null);
86 expect(@typeInfo([10:0]u8).Array.len == 10);
87 expect(@sizeOf([10:0]u8) == 11);
88}85}
8986
90test "type info: C pointer type info" {87test "type info: C pointer type info" {
...@@ -123,10 +120,21 @@ test "type info: array type info" {...@@ -123,10 +120,21 @@ test "type info: array type info" {
123}120}
124121
125fn testArray() void {122fn testArray() void {
126 const arr_info = @typeInfo([42]bool);123 {
127 expect(arr_info == .Array);124 const info = @typeInfo([42]u8);
128 expect(arr_info.Array.len == 42);125 expect(info == .Array);
129 expect(arr_info.Array.child == bool);126 expect(info.Array.len == 42);
127 expect(info.Array.child == u8);
128 expect(info.Array.sentinel == null);
129 }
130
131 {
132 const info = @typeInfo([10:0]u8);
133 expect(info.Array.len == 10);
134 expect(info.Array.child == u8);
135 expect(info.Array.sentinel.? == @as(u8, 0));
136 expect(@sizeOf([10:0]u8) == info.Array.len + 1);
137 }
130}138}
131139
132test "type info: optional type info" {140test "type info: optional type info" {