Commit 5605f6e0e3
Changed files (5)
src/Sema.zig
@@ -25574,6 +25574,22 @@ fn analyzeSlice(
const is_non_null = try sema.analyzeIsNull(block, ptr_src, ptr, true);
try sema.addSafetyCheck(block, is_non_null, .unwrap_null);
}
+
+ if (slice_ty.isSlice()) {
+ const slice_len_inst = try block.addTyOp(.slice_len, Type.usize, ptr_or_slice);
+ const actual_len = if (slice_ty.sentinel() == null)
+ slice_len_inst
+ else
+ try sema.analyzeArithmetic(block, .add, slice_len_inst, .one, src, end_src, end_src);
+
+ const actual_end = if (slice_sentinel != null)
+ try sema.analyzeArithmetic(block, .add, end, .one, src, end_src, end_src)
+ else
+ end;
+
+ try sema.panicIndexOutOfBounds(block, src, actual_end, actual_len, .cmp_lte);
+ }
+
// requirement: result[new_len] == slice_sentinel
try sema.panicSentinelMismatch(block, src, slice_sentinel, elem_ty, result, new_len);
}
@@ -25635,7 +25651,11 @@ fn analyzeSlice(
break :blk try sema.analyzeArithmetic(block, .add, slice_len_inst, .one, src, end_src, end_src);
} else null;
if (opt_len_inst) |len_inst| {
- try sema.panicIndexOutOfBounds(block, src, end, len_inst, .cmp_lte);
+ const actual_end = if (slice_sentinel != null)
+ try sema.analyzeArithmetic(block, .add, end, .one, src, end_src, end_src)
+ else
+ end;
+ try sema.panicIndexOutOfBounds(block, src, actual_end, len_inst, .cmp_lte);
}
// requirement: start <= end
test/cases/safety/cast []u8 to bigger slice of wrong size.zig
@@ -1,9 +1,11 @@
const std = @import("std");
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
- _ = message;
_ = stack_trace;
- std.process.exit(0);
+ if (std.mem.eql(u8, message, "exact division produced remainder")) {
+ std.process.exit(0);
+ }
+ std.process.exit(1);
}
pub fn main() !void {
@@ -15,5 +17,5 @@ fn widenSlice(slice: []align(1) const u8) []align(1) const i32 {
return std.mem.bytesAsSlice(i32, slice);
}
// run
-// backend=stage1
-// target=native
\ No newline at end of file
+// backend=llvm
+// target=native
test/cases/safety/empty slice with sentinel out of bounds.zig
@@ -2,7 +2,7 @@ const std = @import("std");
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
_ = stack_trace;
- if (std.mem.eql(u8, message, "index out of bounds")) {
+ if (std.mem.eql(u8, message, "attempt to index out of bound: index 1, len 0")) {
std.process.exit(0);
}
std.process.exit(1);
@@ -17,5 +17,5 @@ pub fn main() !void {
}
// run
-// backend=stage1
+// backend=llvm
// target=native
test/cases/safety/slice with sentinel out of bounds - runtime len.zig
@@ -0,0 +1,22 @@
+const std = @import("std");
+
+pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ _ = stack_trace;
+ if (std.mem.eql(u8, message, "attempt to index out of bound: index 5, len 4")) {
+ std.process.exit(0);
+ }
+ std.process.exit(1);
+}
+
+pub fn main() !void {
+ var buf = [4]u8{ 'a', 'b', 'c', 0 };
+ const input: []u8 = &buf;
+ var len: usize = 4;
+ const slice = input[0..len :0];
+ _ = slice;
+ return error.TestFailed;
+}
+
+// run
+// backend=llvm
+// target=native
test/cases/safety/slice with sentinel out of bounds.zig
@@ -2,7 +2,7 @@ const std = @import("std");
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
_ = stack_trace;
- if (std.mem.eql(u8, message, "index out of bounds")) {
+ if (std.mem.eql(u8, message, "attempt to index out of bound: index 5, len 4")) {
std.process.exit(0);
}
std.process.exit(1);
@@ -17,5 +17,5 @@ pub fn main() !void {
}
// run
-// backend=stage1
+// backend=llvm
// target=native