From 4fb896f16ebdc9dc6a04a522550524613d467dae Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Thu, 29 Oct 2020 19:38:13 +0100 Subject: [PATCH] stage1: Fix bug in internal string slicing (#6843) Closes #6456 --- src/stage1/ir.cpp | 16 +++++++---- test/stage1/behavior.zig | 1 + test/stage1/behavior/bugs/6456.zig | 43 ++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 5 deletions(-) create mode 100644 test/stage1/behavior/bugs/6456.zig diff --git a/src/stage1/ir.cpp b/src/stage1/ir.cpp index c1d89444a38be70e322dd7d0983e3ffe661b9aac..62d466fa88fb591908ebfba32897e8867ac966f3 100644 --- a/src/stage1/ir.cpp +++ b/src/stage1/ir.cpp @@ -25975,24 +25975,30 @@ static Error get_const_field_buf(IrAnalyze *ira, AstNode *source_node, ZigValue ZigValue *ptr = slice->data.x_struct.fields[slice_ptr_index]; ZigValue *len = slice->data.x_struct.fields[slice_len_index]; assert(ptr->data.x_ptr.special == ConstPtrSpecialBaseArray); - assert(ptr->data.x_ptr.data.base_array.elem_index == 0); ZigValue *arr = ptr->data.x_ptr.data.base_array.array_val; assert(arr->special == ConstValSpecialStatic); + + const size_t start_value = ptr->data.x_ptr.data.base_array.elem_index; + const size_t len_value = bigint_as_usize(&len->data.x_bigint); + switch (arr->data.x_array.special) { case ConstArraySpecialUndef: return ErrorSemanticAnalyzeFail; case ConstArraySpecialNone: { + assert(start_value <= arr->type->data.array.len); + assert(start_value + len_value <= arr->type->data.array.len); buf_resize(out, 0); - size_t count = bigint_as_usize(&len->data.x_bigint); - for (size_t j = 0; j < count; j++) { - ZigValue *ch_val = &arr->data.x_array.data.s_none.elements[j]; + for (size_t j = 0; j < len_value; j++) { + ZigValue *ch_val = &arr->data.x_array.data.s_none.elements[start_value + j]; unsigned ch = bigint_as_u32(&ch_val->data.x_bigint); buf_append_char(out, ch); } break; } case ConstArraySpecialBuf: - buf_init_from_buf(out, arr->data.x_array.data.s_buf); + assert(start_value <= buf_len(arr->data.x_array.data.s_buf)); + assert(start_value + len_value <= buf_len(arr->data.x_array.data.s_buf)); + buf_init_from_mem(out, buf_ptr(arr->data.x_array.data.s_buf) + start_value, len_value); break; } return ErrorNone; diff --git a/test/stage1/behavior.zig b/test/stage1/behavior.zig index 43d38fb6a73e96abb34d4b1e4b50e14a55ead61c..3434f6dbf4203dbfce90825b3e7309b64aa54302 100644 --- a/test/stage1/behavior.zig +++ b/test/stage1/behavior.zig @@ -53,6 +53,7 @@ comptime { _ = @import("behavior/bugs/5413.zig"); _ = @import("behavior/bugs/5474.zig"); _ = @import("behavior/bugs/5487.zig"); + _ = @import("behavior/bugs/6456.zig"); _ = @import("behavior/bugs/6781.zig"); _ = @import("behavior/bugs/6850.zig"); _ = @import("behavior/bugs/394.zig"); diff --git a/test/stage1/behavior/bugs/6456.zig b/test/stage1/behavior/bugs/6456.zig new file mode 100644 index 0000000000000000000000000000000000000000..001e25ec49ece485b75de9a5b92b125f3ea9272f --- /dev/null +++ b/test/stage1/behavior/bugs/6456.zig @@ -0,0 +1,43 @@ +const std = @import("std"); +const testing = std.testing; +const builtin = @import("builtin"); +const StructField = builtin.TypeInfo.StructField; +const Declaration = builtin.TypeInfo.Declaration; + +const text = + \\f1 + \\f2 + \\f3 +; + +test "issue 6456" { + comptime { + var fields: []const StructField = &[0]StructField{}; + + var it = std.mem.tokenize(text, "\n"); + while (it.next()) |name| { + fields = fields ++ &[_]StructField{StructField{ + .alignment = 0, + .name = name, + .field_type = usize, + .default_value = @as(?usize, null), + .is_comptime = false, + }}; + } + + const T = @Type(.{ + .Struct = .{ + .layout = .Auto, + .is_tuple = false, + .fields = fields, + .decls = &[_]Declaration{}, + }, + }); + + const gen_fields = @typeInfo(T).Struct.fields; + testing.expectEqual(3, gen_fields.len); + testing.expectEqualStrings("f1", gen_fields[0].name); + testing.expectEqualStrings("f2", gen_fields[1].name); + testing.expectEqualStrings("f3", gen_fields[2].name); + } +} -- 2.54.0