authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-08-05 17:08:31+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-08-05 22:13:57+03:00
log5605f6e0e302cbf345a5229ea58aef6757fe139d
tree962e8e809a5a116043698b9eda4366c27821466c
parent6aa438f0654569c1713a5c0c49b0bdda20d87c0f

Sema: account for sentinel in bounds check


5 files changed, 53 insertions(+), 9 deletions(-)

src/Sema.zig+21-1
...@@ -25574,6 +25574,22 @@ fn analyzeSlice(...@@ -25574,6 +25574,22 @@ fn analyzeSlice(
25574 const is_non_null = try sema.analyzeIsNull(block, ptr_src, ptr, true);25574 const is_non_null = try sema.analyzeIsNull(block, ptr_src, ptr, true);
25575 try sema.addSafetyCheck(block, is_non_null, .unwrap_null);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 // requirement: result[new_len] == slice_sentinel25593 // requirement: result[new_len] == slice_sentinel
25578 try sema.panicSentinelMismatch(block, src, slice_sentinel, elem_ty, result, new_len);25594 try sema.panicSentinelMismatch(block, src, slice_sentinel, elem_ty, result, new_len);
25579 }25595 }
...@@ -25635,7 +25651,11 @@ fn analyzeSlice(...@@ -25635,7 +25651,11 @@ fn analyzeSlice(
25635 break :blk try sema.analyzeArithmetic(block, .add, slice_len_inst, .one, src, end_src, end_src);25651 break :blk try sema.analyzeArithmetic(block, .add, slice_len_inst, .one, src, end_src, end_src);
25636 } else null;25652 } else null;
25637 if (opt_len_inst) |len_inst| {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 }
2564025660
25641 // requirement: start <= end25661 // requirement: start <= end
test/cases/safety/cast []u8 to bigger slice of wrong size.zig +6-4
...@@ -1,9 +1,11 @@...@@ -1,9 +1,11 @@
1const std = @import("std");1const std = @import("std");
22
3pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {3pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
4 _ = message;
5 _ = stack_trace;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}
810
9pub fn main() !void {11pub fn main() !void {
...@@ -15,5 +17,5 @@ fn widenSlice(slice: []align(1) const u8) []align(1) const i32 {...@@ -15,5 +17,5 @@ fn widenSlice(slice: []align(1) const u8) []align(1) const i32 {
15 return std.mem.bytesAsSlice(i32, slice);17 return std.mem.bytesAsSlice(i32, slice);
16}18}
17// run19// 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,7 +2,7 @@ const std = @import("std");
22
3pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {3pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
4 _ = stack_trace;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 std.process.exit(0);6 std.process.exit(0);
7 }7 }
8 std.process.exit(1);8 std.process.exit(1);
...@@ -17,5 +17,5 @@ pub fn main() !void {...@@ -17,5 +17,5 @@ pub fn main() !void {
17}17}
1818
19// run19// run
20// backend=stage120// backend=llvm
21// target=native21// target=native
test/cases/safety/slice with sentinel out of bounds - runtime len.zig created+22
...@@ -0,0 +1,22 @@
1const std = @import("std");
2
3pub 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
11pub 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,7 +2,7 @@ const std = @import("std");
22
3pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {3pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
4 _ = stack_trace;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 std.process.exit(0);6 std.process.exit(0);
7 }7 }
8 std.process.exit(1);8 std.process.exit(1);
...@@ -17,5 +17,5 @@ pub fn main() !void {...@@ -17,5 +17,5 @@ pub fn main() !void {
17}17}
1818
19// run19// run
20// backend=stage120// backend=llvm
21// target=native21// target=native