aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Sema.zig26
1 files changed, 26 insertions, 0 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index e6447ea2ef..96fabc197f 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -19863,6 +19863,32 @@ fn analyzeSlice(
});
try sema.requireRuntimeBlock(block, src);
+ if (block.wantSafety()) {
+ // requirement: end <= len
+ const opt_len_inst = if (array_ty.zigTypeTag() == .Array)
+ try sema.addIntUnsigned(Type.usize, array_ty.arrayLenIncludingSentinel())
+ else if (slice_ty.isSlice()) blk: {
+ if (try sema.resolveDefinedValue(block, src, ptr_or_slice)) |slice_val| {
+ // we don't need to add one for sentinels because the
+ // underlying value data includes the sentinel
+ break :blk try sema.addIntUnsigned(Type.usize, slice_val.sliceLen());
+ }
+
+ const slice_len_inst = try block.addTyOp(.slice_len, Type.usize, ptr_or_slice);
+ if (slice_ty.sentinel() == null) break :blk slice_len_inst;
+
+ // we have to add one because slice lengths don't include the sentinel
+ break :blk try sema.analyzeArithmetic(block, .add, slice_len_inst, .one, src, end_src, end_src);
+ } else null;
+ if (opt_len_inst) |len_inst| {
+ const end_is_in_bounds = try block.addBinOp(.cmp_lte, end, len_inst);
+ try sema.addSafetyCheck(block, end_is_in_bounds, .index_out_of_bounds);
+ }
+
+ // requirement: start <= end
+ const start_is_in_bounds = try block.addBinOp(.cmp_lte, start, end);
+ try sema.addSafetyCheck(block, start_is_in_bounds, .index_out_of_bounds);
+ }
return block.addInst(.{
.tag = .slice,
.data = .{ .ty_pl = .{