authorgravatar for mitchell.hashimoto@gmail.comMitchell Hashimoto <mitchell.hashimoto@gmail.com> 2022-03-22 14:08:11-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-22 23:41:59-04:00
loge81ebc24e9abf96a6ffbb42cd00587e32e80f23c
treed7c17c0970d22d5e92e19f8d8eda7ce7c9d4f93c
parent47f1a43bb73607b7bdfcb50de2c4ac8d2bc796af

stage2: runtime safety checks for slicing


1 files changed, 26 insertions(+), 0 deletions(-)

src/Sema.zig+26
...@@ -19863,6 +19863,32 @@ fn analyzeSlice(...@@ -19863,6 +19863,32 @@ fn analyzeSlice(
19863 });19863 });
1986419864
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 = .{