| ... | @@ -19863,6 +19863,32 @@ fn analyzeSlice( | ... | @@ -19863,6 +19863,32 @@ fn analyzeSlice( |
| 19863 | }); | 19863 | }); |
| 19864 | | 19864 | |
| 19865 | try sema.requireRuntimeBlock(block, src); | 19865 | try sema.requireRuntimeBlock(block, src); |
| | 19866 | if (block.wantSafety()) { |
| | 19867 | // requirement: end <= len |
| | 19868 | const opt_len_inst = if (array_ty.zigTypeTag() == .Array) |
| | 19869 | try sema.addIntUnsigned(Type.usize, array_ty.arrayLenIncludingSentinel()) |
| | 19870 | else if (slice_ty.isSlice()) blk: { |
| | 19871 | if (try sema.resolveDefinedValue(block, src, ptr_or_slice)) |slice_val| { |
| | 19872 | // we don't need to add one for sentinels because the |
| | 19873 | // underlying value data includes the sentinel |
| | 19874 | break :blk try sema.addIntUnsigned(Type.usize, slice_val.sliceLen()); |
| | 19875 | } |
| | 19876 | |
| | 19877 | const slice_len_inst = try block.addTyOp(.slice_len, Type.usize, ptr_or_slice); |
| | 19878 | if (slice_ty.sentinel() == null) break :blk slice_len_inst; |
| | 19879 | |
| | 19880 | // we have to add one because slice lengths don't include the sentinel |
| | 19881 | break :blk try sema.analyzeArithmetic(block, .add, slice_len_inst, .one, src, end_src, end_src); |
| | 19882 | } else null; |
| | 19883 | if (opt_len_inst) |len_inst| { |
| | 19884 | const end_is_in_bounds = try block.addBinOp(.cmp_lte, end, len_inst); |
| | 19885 | try sema.addSafetyCheck(block, end_is_in_bounds, .index_out_of_bounds); |
| | 19886 | } |
| | 19887 | |
| | 19888 | // requirement: start <= end |
| | 19889 | const start_is_in_bounds = try block.addBinOp(.cmp_lte, start, end); |
| | 19890 | try sema.addSafetyCheck(block, start_is_in_bounds, .index_out_of_bounds); |
| | 19891 | } |
| 19866 | return block.addInst(.{ | 19892 | return block.addInst(.{ |
| 19867 | .tag = .slice, | 19893 | .tag = .slice, |
| 19868 | .data = .{ .ty_pl = .{ | 19894 | .data = .{ .ty_pl = .{ |