Skip to content

Commit 5605f6e

Browse files
committed
Sema: account for sentinel in bounds check
1 parent 6aa438f commit 5605f6e

5 files changed

+53
-9
lines changed

src/Sema.zig

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25574,6 +25574,22 @@ fn analyzeSlice(
2557425574
const is_non_null = try sema.analyzeIsNull(block, ptr_src, ptr, true);
2557525575
try sema.addSafetyCheck(block, is_non_null, .unwrap_null);
2557625576
}
25577+
25578+
if (slice_ty.isSlice()) {
25579+
const slice_len_inst = try block.addTyOp(.slice_len, Type.usize, ptr_or_slice);
25580+
const actual_len = if (slice_ty.sentinel() == null)
25581+
slice_len_inst
25582+
else
25583+
try sema.analyzeArithmetic(block, .add, slice_len_inst, .one, src, end_src, end_src);
25584+
25585+
const actual_end = if (slice_sentinel != null)
25586+
try sema.analyzeArithmetic(block, .add, end, .one, src, end_src, end_src)
25587+
else
25588+
end;
25589+
25590+
try sema.panicIndexOutOfBounds(block, src, actual_end, actual_len, .cmp_lte);
25591+
}
25592+
2557725593
// requirement: result[new_len] == slice_sentinel
2557825594
try sema.panicSentinelMismatch(block, src, slice_sentinel, elem_ty, result, new_len);
2557925595
}
@@ -25635,7 +25651,11 @@ fn analyzeSlice(
2563525651
break :blk try sema.analyzeArithmetic(block, .add, slice_len_inst, .one, src, end_src, end_src);
2563625652
} else null;
2563725653
if (opt_len_inst) |len_inst| {
25638-
try sema.panicIndexOutOfBounds(block, src, end, len_inst, .cmp_lte);
25654+
const actual_end = if (slice_sentinel != null)
25655+
try sema.analyzeArithmetic(block, .add, end, .one, src, end_src, end_src)
25656+
else
25657+
end;
25658+
try sema.panicIndexOutOfBounds(block, src, actual_end, len_inst, .cmp_lte);
2563925659
}
2564025660

2564125661
// requirement: start <= end
Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
const std = @import("std");
22

33
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
4-
_ = message;
54
_ = stack_trace;
6-
std.process.exit(0);
5+
if (std.mem.eql(u8, message, "exact division produced remainder")) {
6+
std.process.exit(0);
7+
}
8+
std.process.exit(1);
79
}
810

911
pub fn main() !void {
@@ -15,5 +17,5 @@ fn widenSlice(slice: []align(1) const u8) []align(1) const i32 {
1517
return std.mem.bytesAsSlice(i32, slice);
1618
}
1719
// run
18-
// backend=stage1
19-
// target=native
20+
// backend=llvm
21+
// target=native

test/cases/safety/empty slice with sentinel out of bounds.zig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ const std = @import("std");
22

33
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
44
_ = stack_trace;
5-
if (std.mem.eql(u8, message, "index out of bounds")) {
5+
if (std.mem.eql(u8, message, "attempt to index out of bound: index 1, len 0")) {
66
std.process.exit(0);
77
}
88
std.process.exit(1);
@@ -17,5 +17,5 @@ pub fn main() !void {
1717
}
1818

1919
// run
20-
// backend=stage1
20+
// backend=llvm
2121
// target=native
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
const std = @import("std");
2+
3+
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
4+
_ = stack_trace;
5+
if (std.mem.eql(u8, message, "attempt to index out of bound: index 5, len 4")) {
6+
std.process.exit(0);
7+
}
8+
std.process.exit(1);
9+
}
10+
11+
pub fn main() !void {
12+
var buf = [4]u8{ 'a', 'b', 'c', 0 };
13+
const input: []u8 = &buf;
14+
var len: usize = 4;
15+
const slice = input[0..len :0];
16+
_ = slice;
17+
return error.TestFailed;
18+
}
19+
20+
// run
21+
// backend=llvm
22+
// target=native

test/cases/safety/slice with sentinel out of bounds.zig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ const std = @import("std");
22

33
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
44
_ = stack_trace;
5-
if (std.mem.eql(u8, message, "index out of bounds")) {
5+
if (std.mem.eql(u8, message, "attempt to index out of bound: index 5, len 4")) {
66
std.process.exit(0);
77
}
88
std.process.exit(1);
@@ -17,5 +17,5 @@ pub fn main() !void {
1717
}
1818

1919
// run
20-
// backend=stage1
20+
// backend=llvm
2121
// target=native

0 commit comments

Comments
 (0)