sema: add compile error for OOB by-length slice of array

This commit is contained in:
dweiller 2023-12-30 14:37:35 +11:00
parent 4129996211
commit 1748511058
3 changed files with 64 additions and 0 deletions

View File

@ -32160,6 +32160,30 @@ fn analyzeSlice(
if (!end_is_len) {
const end = if (by_length) end: {
const len = try sema.coerce(block, Type.usize, uncasted_end_opt, end_src);
if (try sema.resolveValue(len)) |slice_len_val| {
const len_s_val = try mod.intValue(
Type.usize,
array_ty.arrayLenIncludingSentinel(mod),
);
if (!(try sema.compareScalar(slice_len_val, .lte, len_s_val, Type.usize))) {
const sentinel_label: []const u8 = if (array_ty.sentinel(mod) != null)
" +1 (sentinel)"
else
"";
return sema.fail(
block,
end_src,
"length {} out of bounds for array of length {}{s}",
.{
slice_len_val.fmtValue(Type.usize, mod),
len_val.fmtValue(Type.usize, mod),
sentinel_label,
},
);
}
}
// check len is less than array size if comptime known
const uncasted_end = try sema.analyzeArithmetic(block, .add, start, len, src, start_src, end_src, false);
break :end try sema.coerce(block, Type.usize, uncasted_end, end_src);
} else try sema.coerce(block, Type.usize, uncasted_end_opt, end_src);

View File

@ -0,0 +1,19 @@
export fn entry1() void {
var buf: [5]u8 = undefined;
var a: u32 = 6;
_ = &a;
_ = buf[a..][0..10];
}
export fn entry2() void {
var buf: [5]u8 = undefined;
const a: u32 = 6;
_ = buf[a..][0..10];
}
// error
// backend=stage2
// target=native
//
// :5:21: error: length 10 out of bounds for array of length 5
// :11:21: error: length 10 out of bounds for array of length 5

View File

@ -0,0 +1,21 @@
const std = @import("std");
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn {
_ = stack_trace;
if (std.mem.eql(u8, message, "index out of bounds: index 12, len 5")) {
std.process.exit(0);
}
std.process.exit(1);
}
pub fn main() !void {
var buf: [5]u8 = undefined;
var a: u32 = 6;
_ = &a;
_ = buf[a..][0..a];
return error.TestFailed;
}
// run
// backend=llvm
// target=native