authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-10-29 19:38:13+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2020-10-29 14:38:13-04:00
log4fb896f16ebdc9dc6a04a522550524613d467dae
treef9c1b37c17ff15e81ac25295678c1bd8cb612c55
parent6f3c84834d29e632267438bd6a5d5589b0b074e5
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

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

Closes #6456

3 files changed, 55 insertions(+), 5 deletions(-)

src/stage1/ir.cpp+11-5
...@@ -25975,24 +25975,30 @@ static Error get_const_field_buf(IrAnalyze *ira, AstNode *source_node, ZigValue...@@ -25975,24 +25975,30 @@ static Error get_const_field_buf(IrAnalyze *ira, AstNode *source_node, ZigValue
25975 ZigValue *ptr = slice->data.x_struct.fields[slice_ptr_index];25975 ZigValue *ptr = slice->data.x_struct.fields[slice_ptr_index];
25976 ZigValue *len = slice->data.x_struct.fields[slice_len_index];25976 ZigValue *len = slice->data.x_struct.fields[slice_len_index];
25977 assert(ptr->data.x_ptr.special == ConstPtrSpecialBaseArray);25977 assert(ptr->data.x_ptr.special == ConstPtrSpecialBaseArray);
25978 assert(ptr->data.x_ptr.data.base_array.elem_index == 0);
25979 ZigValue *arr = ptr->data.x_ptr.data.base_array.array_val;25978 ZigValue *arr = ptr->data.x_ptr.data.base_array.array_val;
25980 assert(arr->special == ConstValSpecialStatic);25979 assert(arr->special == ConstValSpecialStatic);
25980
25981 const size_t start_value = ptr->data.x_ptr.data.base_array.elem_index;
25982 const size_t len_value = bigint_as_usize(&len->data.x_bigint);
25983
25981 switch (arr->data.x_array.special) {25984 switch (arr->data.x_array.special) {
25982 case ConstArraySpecialUndef:25985 case ConstArraySpecialUndef:
25983 return ErrorSemanticAnalyzeFail;25986 return ErrorSemanticAnalyzeFail;
25984 case ConstArraySpecialNone: {25987 case ConstArraySpecialNone: {
25988 assert(start_value <= arr->type->data.array.len);
25989 assert(start_value + len_value <= arr->type->data.array.len);
25985 buf_resize(out, 0);25990 buf_resize(out, 0);
25986 size_t count = bigint_as_usize(&len->data.x_bigint);25991 for (size_t j = 0; j < len_value; j++) {
25987 for (size_t j = 0; j < count; j++) {25992 ZigValue *ch_val = &arr->data.x_array.data.s_none.elements[start_value + j];
25988 ZigValue *ch_val = &arr->data.x_array.data.s_none.elements[j];
25989 unsigned ch = bigint_as_u32(&ch_val->data.x_bigint);25993 unsigned ch = bigint_as_u32(&ch_val->data.x_bigint);
25990 buf_append_char(out, ch);25994 buf_append_char(out, ch);
25991 }25995 }
25992 break;25996 break;
25993 }25997 }
25994 case ConstArraySpecialBuf:25998 case ConstArraySpecialBuf:
25995 buf_init_from_buf(out, arr->data.x_array.data.s_buf);25999 assert(start_value <= buf_len(arr->data.x_array.data.s_buf));
26000 assert(start_value + len_value <= buf_len(arr->data.x_array.data.s_buf));
26001 buf_init_from_mem(out, buf_ptr(arr->data.x_array.data.s_buf) + start_value, len_value);
25996 break;26002 break;
25997 }26003 }
25998 return ErrorNone;26004 return ErrorNone;
test/stage1/behavior.zig+1
...@@ -53,6 +53,7 @@ comptime {...@@ -53,6 +53,7 @@ comptime {
53 _ = @import("behavior/bugs/5413.zig");53 _ = @import("behavior/bugs/5413.zig");
54 _ = @import("behavior/bugs/5474.zig");54 _ = @import("behavior/bugs/5474.zig");
55 _ = @import("behavior/bugs/5487.zig");55 _ = @import("behavior/bugs/5487.zig");
56 _ = @import("behavior/bugs/6456.zig");
56 _ = @import("behavior/bugs/6781.zig");57 _ = @import("behavior/bugs/6781.zig");
57 _ = @import("behavior/bugs/6850.zig");58 _ = @import("behavior/bugs/6850.zig");
58 _ = @import("behavior/bugs/394.zig");59 _ = @import("behavior/bugs/394.zig");
test/stage1/behavior/bugs/6456.zig created+43
...@@ -0,0 +1,43 @@
1const std = @import("std");
2const testing = std.testing;
3const builtin = @import("builtin");
4const StructField = builtin.TypeInfo.StructField;
5const Declaration = builtin.TypeInfo.Declaration;
6
7const text =
8 \\f1
9 \\f2
10 \\f3
11;
12
13test "issue 6456" {
14 comptime {
15 var fields: []const StructField = &[0]StructField{};
16
17 var it = std.mem.tokenize(text, "\n");
18 while (it.next()) |name| {
19 fields = fields ++ &[_]StructField{StructField{
20 .alignment = 0,
21 .name = name,
22 .field_type = usize,
23 .default_value = @as(?usize, null),
24 .is_comptime = false,
25 }};
26 }
27
28 const T = @Type(.{
29 .Struct = .{
30 .layout = .Auto,
31 .is_tuple = false,
32 .fields = fields,
33 .decls = &[_]Declaration{},
34 },
35 });
36
37 const gen_fields = @typeInfo(T).Struct.fields;
38 testing.expectEqual(3, gen_fields.len);
39 testing.expectEqualStrings("f1", gen_fields[0].name);
40 testing.expectEqualStrings("f2", gen_fields[1].name);
41 testing.expectEqualStrings("f3", gen_fields[2].name);
42 }
43}