Commit 4fb896f16e

LemonBoy <LemonBoy@users.noreply.github.com>
2020-10-29 19:38:13
stage1: Fix bug in internal string slicing (#6843)
Closes #6456
1 parent 6f3c848
Changed files (3)
src
stage1
test
stage1
behavior
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;
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);
+    }
+}
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");