| author | |
| committer | |
| log | 5605f6e0e302cbf345a5229ea58aef6757fe139d |
| tree | 962e8e809a5a116043698b9eda4366c27821466c |
| parent | 6aa438f0654569c1713a5c0c49b0bdda20d87c0f |
5 files changed, 53 insertions(+), 9 deletions(-)
src/Sema.zig+21-1| ... | ... | @@ -25574,6 +25574,22 @@ fn analyzeSlice( |
| 25574 | 25574 | const is_non_null = try sema.analyzeIsNull(block, ptr_src, ptr, true); |
| 25575 | 25575 | try sema.addSafetyCheck(block, is_non_null, .unwrap_null); |
| 25576 | 25576 | } |
| 25577 | ||
| 25578 | if (slice_ty.isSlice()) { | |
| 25579 | const slice_len_inst = try block.addTyOp(.slice_len, Type.usize, ptr_or_slice); | |
| 25580 | const actual_len = if (slice_ty.sentinel() == null) | |
| 25581 | slice_len_inst | |
| 25582 | else | |
| 25583 | try sema.analyzeArithmetic(block, .add, slice_len_inst, .one, src, end_src, end_src); | |
| 25584 | ||
| 25585 | const actual_end = if (slice_sentinel != null) | |
| 25586 | try sema.analyzeArithmetic(block, .add, end, .one, src, end_src, end_src) | |
| 25587 | else | |
| 25588 | end; | |
| 25589 | ||
| 25590 | try sema.panicIndexOutOfBounds(block, src, actual_end, actual_len, .cmp_lte); | |
| 25591 | } | |
| 25592 | ||
| 25577 | 25593 | // requirement: result[new_len] == slice_sentinel |
| 25578 | 25594 | try sema.panicSentinelMismatch(block, src, slice_sentinel, elem_ty, result, new_len); |
| 25579 | 25595 | } |
| ... | ... | @@ -25635,7 +25651,11 @@ fn analyzeSlice( |
| 25635 | 25651 | break :blk try sema.analyzeArithmetic(block, .add, slice_len_inst, .one, src, end_src, end_src); |
| 25636 | 25652 | } else null; |
| 25637 | 25653 | if (opt_len_inst) |len_inst| { |
| 25638 | try sema.panicIndexOutOfBounds(block, src, end, len_inst, .cmp_lte); | |
| 25654 | const actual_end = if (slice_sentinel != null) | |
| 25655 | try sema.analyzeArithmetic(block, .add, end, .one, src, end_src, end_src) | |
| 25656 | else | |
| 25657 | end; | |
| 25658 | try sema.panicIndexOutOfBounds(block, src, actual_end, len_inst, .cmp_lte); | |
| 25639 | 25659 | } |
| 25640 | 25660 | |
| 25641 | 25661 | // requirement: start <= end |
test/cases/safety/cast []u8 to bigger slice of wrong size.zig	+6-4| ... | ... | @@ -1,9 +1,11 @@ |
| 1 | 1 | const std = @import("std"); |
| 2 | 2 | |
| 3 | 3 | pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { |
| 4 | _ = message; | |
| 5 | 4 | _ = stack_trace; |
| 6 | std.process.exit(0); | |
| 5 | if (std.mem.eql(u8, message, "exact division produced remainder")) { | |
| 6 | std.process.exit(0); | |
| 7 | } | |
| 8 | std.process.exit(1); | |
| 7 | 9 | } |
| 8 | 10 | |
| 9 | 11 | pub fn main() !void { |
| ... | ... | @@ -15,5 +17,5 @@ fn widenSlice(slice: []align(1) const u8) []align(1) const i32 { |
| 15 | 17 | return std.mem.bytesAsSlice(i32, slice); |
| 16 | 18 | } |
| 17 | 19 | // run |
| 18 | // backend=stage1 | |
| 19 | // target=native | |
| \ No newline at end of file | ||
| 20 | // backend=llvm | |
| 21 | // target=native |
test/cases/safety/empty slice with sentinel out of bounds.zig	+2-2| ... | ... | @@ -2,7 +2,7 @@ const std = @import("std"); |
| 2 | 2 | |
| 3 | 3 | pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { |
| 4 | 4 | _ = stack_trace; |
| 5 | if (std.mem.eql(u8, message, "index out of bounds")) { | |
| 5 | if (std.mem.eql(u8, message, "attempt to index out of bound: index 1, len 0")) { | |
| 6 | 6 | std.process.exit(0); |
| 7 | 7 | } |
| 8 | 8 | std.process.exit(1); |
| ... | ... | @@ -17,5 +17,5 @@ pub fn main() !void { |
| 17 | 17 | } |
| 18 | 18 | |
| 19 | 19 | // run |
| 20 | // backend=stage1 | |
| 20 | // backend=llvm | |
| 21 | 21 | // target=native |
test/cases/safety/slice with sentinel out of bounds - runtime len.zig	 created+22| ... | ... | @@ -0,0 +1,22 @@ |
| 1 | const std = @import("std"); | |
| 2 | ||
| 3 | pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { | |
| 4 | _ = stack_trace; | |
| 5 | if (std.mem.eql(u8, message, "attempt to index out of bound: index 5, len 4")) { | |
| 6 | std.process.exit(0); | |
| 7 | } | |
| 8 | std.process.exit(1); | |
| 9 | } | |
| 10 | ||
| 11 | pub fn main() !void { | |
| 12 | var buf = [4]u8{ 'a', 'b', 'c', 0 }; | |
| 13 | const input: []u8 = &buf; | |
| 14 | var len: usize = 4; | |
| 15 | const slice = input[0..len :0]; | |
| 16 | _ = slice; | |
| 17 | return error.TestFailed; | |
| 18 | } | |
| 19 | ||
| 20 | // run | |
| 21 | // backend=llvm | |
| 22 | // target=native |
test/cases/safety/slice with sentinel out of bounds.zig	+2-2| ... | ... | @@ -2,7 +2,7 @@ const std = @import("std"); |
| 2 | 2 | |
| 3 | 3 | pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { |
| 4 | 4 | _ = stack_trace; |
| 5 | if (std.mem.eql(u8, message, "index out of bounds")) { | |
| 5 | if (std.mem.eql(u8, message, "attempt to index out of bound: index 5, len 4")) { | |
| 6 | 6 | std.process.exit(0); |
| 7 | 7 | } |
| 8 | 8 | std.process.exit(1); |
| ... | ... | @@ -17,5 +17,5 @@ pub fn main() !void { |
| 17 | 17 | } |
| 18 | 18 | |
| 19 | 19 | // run |
| 20 | // backend=stage1 | |
| 20 | // backend=llvm | |
| 21 | 21 | // target=native |