zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 4fb896f16ebdc9dc6a04a522550524613d467dae (tree)
parent 6f3c84834d29e632267438bd6a5d5589b0b074e5
Author: LemonBoy <LemonBoy@users.noreply.github.com>
Date:   Thu, 29 Oct 2020 19:38:13 +0100

stage1: Fix bug in internal string slicing (#6843)

Closes #6456

Diffstat:
Msrc/stage1/ir.cpp | 16+++++++++++-----
Mtest/stage1/behavior.zig | 1+
Atest/stage1/behavior/bugs/6456.zig | 43+++++++++++++++++++++++++++++++++++++++++++
3 files changed, 55 insertions(+), 5 deletions(-)

diff --git 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 @@ -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 @@ -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); + } +}