Skip to content

Commit 4fb896f

Browse files
authored
stage1: Fix bug in internal string slicing (#6843)
Closes #6456
1 parent 6f3c848 commit 4fb896f

File tree

3 files changed

+55
-5
lines changed

3 files changed

+55
-5
lines changed

src/stage1/ir.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25975,24 +25975,30 @@ static Error get_const_field_buf(IrAnalyze *ira, AstNode *source_node, ZigValue
2597525975
ZigValue *ptr = slice->data.x_struct.fields[slice_ptr_index];
2597625976
ZigValue *len = slice->data.x_struct.fields[slice_len_index];
2597725977
assert(ptr->data.x_ptr.special == ConstPtrSpecialBaseArray);
25978-
assert(ptr->data.x_ptr.data.base_array.elem_index == 0);
2597925978
ZigValue *arr = ptr->data.x_ptr.data.base_array.array_val;
2598025979
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+
2598125984
switch (arr->data.x_array.special) {
2598225985
case ConstArraySpecialUndef:
2598325986
return ErrorSemanticAnalyzeFail;
2598425987
case ConstArraySpecialNone: {
25988+
assert(start_value <= arr->type->data.array.len);
25989+
assert(start_value + len_value <= arr->type->data.array.len);
2598525990
buf_resize(out, 0);
25986-
size_t count = bigint_as_usize(&len->data.x_bigint);
25987-
for (size_t j = 0; j < count; j++) {
25988-
ZigValue *ch_val = &arr->data.x_array.data.s_none.elements[j];
25991+
for (size_t j = 0; j < len_value; j++) {
25992+
ZigValue *ch_val = &arr->data.x_array.data.s_none.elements[start_value + j];
2598925993
unsigned ch = bigint_as_u32(&ch_val->data.x_bigint);
2599025994
buf_append_char(out, ch);
2599125995
}
2599225996
break;
2599325997
}
2599425998
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);
2599626002
break;
2599726003
}
2599826004
return ErrorNone;

test/stage1/behavior.zig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ comptime {
5353
_ = @import("behavior/bugs/5413.zig");
5454
_ = @import("behavior/bugs/5474.zig");
5555
_ = @import("behavior/bugs/5487.zig");
56+
_ = @import("behavior/bugs/6456.zig");
5657
_ = @import("behavior/bugs/6781.zig");
5758
_ = @import("behavior/bugs/6850.zig");
5859
_ = @import("behavior/bugs/394.zig");

test/stage1/behavior/bugs/6456.zig

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
const std = @import("std");
2+
const testing = std.testing;
3+
const builtin = @import("builtin");
4+
const StructField = builtin.TypeInfo.StructField;
5+
const Declaration = builtin.TypeInfo.Declaration;
6+
7+
const text =
8+
\\f1
9+
\\f2
10+
\\f3
11+
;
12+
13+
test "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+
}

0 commit comments

Comments
 (0)