Sema: account for sentinel in bounds check
This commit is contained in:
22
src/Sema.zig
22
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
|
||||
|
||||
@@ -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
|
||||
// backend=llvm
|
||||
// target=native
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user