authorgravatar for mitchell.hashimoto@gmail.comMitchell Hashimoto <mitchell.hashimoto@gmail.com> 2022-03-20 20:04:18-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-21 22:10:34-04:00
log91fd0f42c88f4bea424b5a5c58435a2a98b57a58
tree37645cd0c83902451b59492dea2ad75db77cb06e
parent0fb005d1d05acb680389ce8be51bab6020309922

stage2: out of bounds error for slicing


3 files changed, 58 insertions(+), 1 deletions(-)

src/Sema.zig+30
......@@ -19587,6 +19587,14 @@ fn analyzeSlice(
1958719587 if (!end_is_len) {
1958819588 const end = try sema.coerce(block, Type.usize, uncasted_end_opt, end_src);
1958919589 if (try sema.resolveMaybeUndefVal(block, end_src, end)) |end_val| {
19590 if (end_val.compare(.gt, len_val, Type.usize)) {
19591 return sema.fail(
19592 block,
19593 end_src,
19594 "end index {} out of bounds for array of length {}",
19595 .{ end_val.fmtValue(Type.usize), len_val.fmtValue(Type.usize) },
19596 );
19597 }
1959019598 if (end_val.eql(len_val, Type.usize)) {
1959119599 end_is_len = true;
1959219600 }
......@@ -19605,6 +19613,14 @@ fn analyzeSlice(
1960519613 .data = slice_val.sliceLen(),
1960619614 };
1960719615 const slice_len_val = Value.initPayload(&int_payload.base);
19616 if (end_val.compare(.gt, slice_len_val, Type.usize)) {
19617 return sema.fail(
19618 block,
19619 end_src,
19620 "end index {} out of bounds for slice of length {}",
19621 .{ end_val.fmtValue(Type.usize), slice_len_val.fmtValue(Type.usize) },
19622 );
19623 }
1960819624 if (end_val.eql(slice_len_val, Type.usize)) {
1960919625 end_is_len = true;
1961019626 }
......@@ -19635,6 +19651,20 @@ fn analyzeSlice(
1963519651 break :s null;
1963619652 };
1963719653
19654 // requirement: start <= end
19655 if (try sema.resolveDefinedValue(block, src, end)) |end_val| {
19656 if (try sema.resolveDefinedValue(block, src, start)) |start_val| {
19657 if (start_val.compare(.gt, end_val, Type.usize)) {
19658 return sema.fail(
19659 block,
19660 start_src,
19661 "start index {} is larger than end index {}",
19662 .{ start_val.fmtValue(Type.usize), end_val.fmtValue(Type.usize) },
19663 );
19664 }
19665 }
19666 }
19667
1963819668 const new_len = try sema.analyzeArithmetic(block, .sub, end, start, src, end_src, start_src);
1963919669 const opt_new_len_val = try sema.resolveDefinedValue(block, src, new_len);
1964019670
test/behavior/cast.zig+5-1
......@@ -906,7 +906,11 @@ test "peer cast [*:x]T to [*]T" {
906906}
907907
908908test "peer cast [:x]T to [*:x]T" {
909 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
909 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
910 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
911 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
912 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
913 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
910914
911915 const S = struct {
912916 fn doTheTest() !void {
test/compile_errors.zig+23
......@@ -21,6 +21,29 @@ pub fn addCases(ctx: *TestContext) !void {
2121 , &[_][]const u8{
2222 ":2:20: error: import of file outside package path: '../../above.zig'",
2323 });
24
25 case.addError(
26 \\comptime {
27 \\ var array = [_:0]u8{ 1, 2, 3, 4 };
28 \\ var src_slice: [:0]u8 = &array;
29 \\ var slice = src_slice[2..5];
30 \\ _ = slice;
31 \\}
32 \\comptime {
33 \\ var array = [_:0]u8{ 1, 2, 3, 4 };
34 \\ var slice = array[2..5];
35 \\ _ = slice;
36 \\}
37 \\comptime {
38 \\ var array = [_:0]u8{ 1, 2, 3, 4 };
39 \\ var slice = array[3..2];
40 \\ _ = slice;
41 \\}
42 , &[_][]const u8{
43 ":4:26: error: end index 5 out of bounds for slice of length 4",
44 ":9:22: error: end index 5 out of bounds for array of length 4",
45 ":14:22: error: start index 3 is larger than end index 2",
46 });
2447 }
2548
2649 ctx.objErrStage1("exported enum without explicit integer tag type",