diff --git a/src/Sema.zig b/src/Sema.zig index d0b0efcf1976..0232fa94252e 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -33094,19 +33094,23 @@ fn analyzeSlice( try sema.addSafetyCheck(block, src, is_non_null, .unwrap_null); } - if (slice_ty.isSlice(mod)) { + const opt_len_inst = if (array_ty.zigTypeTag(mod) == .Array) + try mod.intRef(Type.usize, array_ty.arrayLenIncludingSentinel(mod)) + else if (slice_ty.isSlice(mod)) blk: { const slice_len_inst = try block.addTyOp(.slice_len, Type.usize, ptr_or_slice); const actual_len = if (slice_ty.sentinel(mod) == null) slice_len_inst else try sema.analyzeArithmetic(block, .add, slice_len_inst, .one, src, end_src, end_src, true); - + break :blk actual_len; + } else null; + if (opt_len_inst) |len_inst| { const actual_end = if (slice_sentinel != null) try sema.analyzeArithmetic(block, .add, end, .one, src, end_src, end_src, true) else end; - try sema.panicIndexOutOfBounds(block, src, actual_end, actual_len, .cmp_lte); + try sema.panicIndexOutOfBounds(block, src, actual_end, len_inst, .cmp_lte); } // requirement: result[new_len] == slice_sentinel diff --git a/test/cases/safety/slicing by-length out-of-bounds comptime length.zig b/test/cases/safety/slicing by-length out-of-bounds comptime length.zig new file mode 100644 index 000000000000..a240312617e7 --- /dev/null +++ b/test/cases/safety/slicing by-length out-of-bounds comptime length.zig @@ -0,0 +1,20 @@ +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 16, 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..10]; + return error.TestFailed; +} +// run +// backend=llvm +// target=native diff --git a/test/cases/safety/slicing by-length out-of-bounds runtime length.zig b/test/cases/safety/slicing by-length out-of-bounds runtime length.zig new file mode 100644 index 000000000000..dcf78c1e2443 --- /dev/null +++ b/test/cases/safety/slicing by-length out-of-bounds runtime length.zig @@ -0,0 +1,22 @@ +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 16, len 5")) { + std.process.exit(0); + } + std.process.exit(1); +} + +pub fn main() !void { + var buf: [5]u8 = undefined; + var a: u32 = 6; + _ = &a; + var len: u32 = 10; + _ = &len; + _ = buf[a..][0..len]; + return error.TestFailed; +} +// run +// backend=llvm +// target=native