authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-08-05 16:50:27+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-08-05 22:13:57+03:00
log6aa438f0654569c1713a5c0c49b0bdda20d87c0f
tree4a903310bc1153af77490332b79c425d38b1fa30
parenteec2978fac240f6852873bdd9a3ae03b77df6199

Sema: add null pointer slice safety check when len is comptime known


7 files changed, 42 insertions(+), 15 deletions(-)

src/Sema.zig+5
...@@ -25569,6 +25569,11 @@ fn analyzeSlice(...@@ -25569,6 +25569,11 @@ fn analyzeSlice(
25569 const new_ptr_val = opt_new_ptr_val orelse {25569 const new_ptr_val = opt_new_ptr_val orelse {
25570 const result = try block.addBitCast(return_ty, new_ptr);25570 const result = try block.addBitCast(return_ty, new_ptr);
25571 if (block.wantSafety()) {25571 if (block.wantSafety()) {
25572 // requirement: slicing C ptr is non-null
25573 if (ptr_ptr_child_ty.isCPtr()) {
25574 const is_non_null = try sema.analyzeIsNull(block, ptr_src, ptr, true);
25575 try sema.addSafetyCheck(block, is_non_null, .unwrap_null);
25576 }
25572 // requirement: result[new_len] == slice_sentinel25577 // requirement: result[new_len] == slice_sentinel
25573 try sema.panicSentinelMismatch(block, src, slice_sentinel, elem_ty, result, new_len);25578 try sema.panicSentinelMismatch(block, src, slice_sentinel, elem_ty, result, new_len);
25574 }25579 }
test/cases/safety/pointer slice sentinel mismatch.zig +3-3
...@@ -2,14 +2,14 @@ const std = @import("std");...@@ -2,14 +2,14 @@ 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, "sentinel mismatch")) {5 if (std.mem.eql(u8, message, "sentinel mismatch: expected 0, found 4")) {
6 std.process.exit(0);6 std.process.exit(0);
7 }7 }
8 std.process.exit(1);8 std.process.exit(1);
9}9}
1010
11pub fn main() !void {11pub fn main() !void {
12 var buf: [4]u8 = undefined;12 var buf: [4]u8 = .{ 1, 2, 3, 4 };
13 const ptr: [*]u8 = &buf;13 const ptr: [*]u8 = &buf;
14 const slice = ptr[0..3 :0];14 const slice = ptr[0..3 :0];
15 _ = slice;15 _ = slice;
...@@ -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 sentinel mismatch - floats.zig +3-3
...@@ -2,19 +2,19 @@ const std = @import("std");...@@ -2,19 +2,19 @@ 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, "sentinel mismatch")) {5 if (std.mem.eql(u8, message, "sentinel mismatch: expected 1.20000004e+00, found 4.0e+00")) {
6 std.process.exit(0);6 std.process.exit(0);
7 }7 }
8 std.process.exit(1);8 std.process.exit(1);
9}9}
1010
11pub fn main() !void {11pub fn main() !void {
12 var buf: [4]f32 = undefined;12 var buf: [4]f32 = .{ 1, 2, 3, 4 };
13 const slice = buf[0..3 :1.2];13 const slice = buf[0..3 :1.2];
14 _ = slice;14 _ = slice;
15 return error.TestFailed;15 return error.TestFailed;
16}16}
1717
18// run18// run
19// backend=stage119// backend=llvm
20// target=native20// target=native
test/cases/safety/slice sentinel mismatch - optional pointers.zig +3-3
...@@ -2,19 +2,19 @@ const std = @import("std");...@@ -2,19 +2,19 @@ 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, "sentinel mismatch")) {5 if (std.mem.eql(u8, message, "sentinel mismatch: expected null, found i32@10")) {
6 std.process.exit(0);6 std.process.exit(0);
7 }7 }
8 std.process.exit(1);8 std.process.exit(1);
9}9}
1010
11pub fn main() !void {11pub fn main() !void {
12 var buf: [4]?*i32 = undefined;12 var buf: [4]?*i32 = .{ @intToPtr(*i32, 4), @intToPtr(*i32, 8), @intToPtr(*i32, 12), @intToPtr(*i32, 16) };
13 const slice = buf[0..3 :null];13 const slice = buf[0..3 :null];
14 _ = slice;14 _ = slice;
15 return error.TestFailed;15 return error.TestFailed;
16}16}
1717
18// run18// run
19// backend=stage119// backend=llvm
20// target=native20// target=native
test/cases/safety/slice slice sentinel mismatch.zig +3-3
...@@ -2,18 +2,18 @@ const std = @import("std");...@@ -2,18 +2,18 @@ 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, "sentinel mismatch")) {5 if (std.mem.eql(u8, message, "sentinel mismatch: expected 0, found 4")) {
6 std.process.exit(0);6 std.process.exit(0);
7 }7 }
8 std.process.exit(1);8 std.process.exit(1);
9}9}
10pub fn main() !void {10pub fn main() !void {
11 var buf: [4]u8 = undefined;11 var buf: [4]u8 = .{ 1, 2, 3, 4 };
12 const slice = buf[0..];12 const slice = buf[0..];
13 const slice2 = slice[0..3 :0];13 const slice2 = slice[0..3 :0];
14 _ = slice2;14 _ = slice2;
15 return error.TestFailed;15 return error.TestFailed;
16}16}
17// run17// run
18// backend=stage118// backend=llvm
19// target=native19// target=native
test/cases/safety/slicing null C pointer runtime len.zig created+20
...@@ -0,0 +1,20 @@
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 use null value")) {
6 std.process.exit(0);
7 }
8 std.process.exit(1);
9}
10
11pub fn main() !void {
12 var ptr: [*c]const u32 = null;
13 var len: usize = 3;
14 var slice = ptr[0..len];
15 _ = slice;
16 return error.TestFailed;
17}
18// run
19// backend=llvm
20// target=native
\ No newline at end of file
test/cases/safety/slicing null C pointer.zig +5-3
...@@ -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, "attempt to use null value")) {
6 std.process.exit(0);
7 }
8 std.process.exit(1);
7}9}
810
9pub fn main() !void {11pub fn main() !void {
...@@ -13,5 +15,5 @@ pub fn main() !void {...@@ -13,5 +15,5 @@ pub fn main() !void {
13 return error.TestFailed;15 return error.TestFailed;
14}16}
15// run17// run
16// backend=stage118// backend=llvm
17// target=native19// target=native
\ No newline at end of file