From a7c2cfe16d4267ea4e4719568c12a7a950374b0c Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sun, 29 Nov 2020 12:39:15 +0100 Subject: [PATCH] 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 --- src/stage1/ir.cpp | 16 ++++++++++------ test/stage1/behavior/type_info.zig | 22 +++++++++++++++------- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/stage1/ir.cpp b/src/stage1/ir.cpp index 4e53e3738e..7b0d83d957 100644 --- a/src/stage1/ir.cpp +++ b/src/stage1/ir.cpp @@ -25062,12 +25062,12 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInst* source_instr, ZigVa 0, 0, 0, false); fn_decl_fields[5]->type = get_optional_type(ira->codegen, get_slice_type(ira->codegen, u8_ptr)); if (fn_node->is_extern && fn_node->lib_name != nullptr && buf_len(fn_node->lib_name) > 0) { - fn_decl_fields[5]->data.x_optional = ira->codegen->pass1_arena->create(); + ZigValue *slice_val = ira->codegen->pass1_arena->create(); ZigValue *lib_name = create_const_str_lit(ira->codegen, fn_node->lib_name)->data.x_ptr.data.ref.pointee; - init_const_slice(ira->codegen, fn_decl_fields[5]->data.x_optional, lib_name, 0, - buf_len(fn_node->lib_name), true); + init_const_slice(ira->codegen, slice_val, lib_name, 0, buf_len(fn_node->lib_name), true); + set_optional_payload(fn_decl_fields[5], slice_val); } else { - fn_decl_fields[5]->data.x_optional = nullptr; + set_optional_payload(fn_decl_fields[5], nullptr); } // return_type: type 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 fields[1]->data.x_type = type_entry->data.array.child_type; // sentinel: anytype fields[2]->special = ConstValSpecialStatic; - fields[2]->type = get_optional_type(ira->codegen, type_entry->data.array.child_type); - fields[2]->data.x_optional = type_entry->data.array.sentinel; + if (type_entry->data.array.child_type != nullptr) { + fields[2]->type = get_optional_type(ira->codegen, type_entry->data.array.child_type); + set_optional_payload(fields[2], type_entry->data.array.sentinel); + } else { + fields[2]->type = ira->codegen->builtin_types.entry_null; + } break; } case ZigTypeIdVector: { diff --git a/test/stage1/behavior/type_info.zig b/test/stage1/behavior/type_info.zig index e08c0b16b8..e197fb7f41 100644 --- a/test/stage1/behavior/type_info.zig +++ b/test/stage1/behavior/type_info.zig @@ -82,9 +82,6 @@ fn testNullTerminatedPtr() void { expect(ptr_info.Pointer.sentinel.? == 0); expect(@typeInfo([:0]u8).Pointer.sentinel != null); - expect(@typeInfo([10:0]u8).Array.sentinel != null); - expect(@typeInfo([10:0]u8).Array.len == 10); - expect(@sizeOf([10:0]u8) == 11); } test "type info: C pointer type info" { @@ -123,10 +120,21 @@ test "type info: array type info" { } fn testArray() void { - const arr_info = @typeInfo([42]bool); - expect(arr_info == .Array); - expect(arr_info.Array.len == 42); - expect(arr_info.Array.child == bool); + { + const info = @typeInfo([42]u8); + expect(info == .Array); + expect(info.Array.len == 42); + expect(info.Array.child == u8); + expect(info.Array.sentinel == null); + } + + { + const info = @typeInfo([10:0]u8); + expect(info.Array.len == 10); + expect(info.Array.child == u8); + expect(info.Array.sentinel.? == @as(u8, 0)); + expect(@sizeOf([10:0]u8) == info.Array.len + 1); + } } test "type info: optional type info" {