authorgravatar for mitchell.hashimoto@gmail.comMitchell Hashimoto <mitchell.hashimoto@gmail.com> 2022-03-25 09:09:32-07:00
committergravatar for mitchell.hashimoto@gmail.comMitchell Hashimoto <mitchell.hashimoto@gmail.com> 2022-03-27 09:20:35-07:00
log01698528d1dff627b7e057651b137c20df7c7231
tree1f9238b1eaaf69ddfb7b8750d590b1f5fb9d54a9
parentd15bbebe2e6b8fcbfcd730a6c0d1be621b27045d
signature Commit is signed but in an unrecognized format.

stage2: safety checks for slicing a null C pointer


3 files changed, 25 insertions(+), 0 deletions(-)

src/Sema.zig+14
...@@ -19964,6 +19964,14 @@ fn analyzeSlice(...@@ -19964,6 +19964,14 @@ fn analyzeSlice(
19964 slice_ty = ptr_ptr_child_ty;19964 slice_ty = ptr_ptr_child_ty;
19965 array_ty = ptr_ptr_child_ty;19965 array_ty = ptr_ptr_child_ty;
19966 elem_ty = ptr_ptr_child_ty.childType();19966 elem_ty = ptr_ptr_child_ty.childType();
19967
19968 if (ptr_ptr_child_ty.ptrSize() == .C) {
19969 if (try sema.resolveDefinedValue(block, ptr_src, ptr_or_slice)) |ptr_val| {
19970 if (ptr_val.isNull()) {
19971 return sema.fail(block, ptr_src, "slice of null pointer", .{});
19972 }
19973 }
19974 }
19967 },19975 },
19968 .Slice => {19976 .Slice => {
19969 ptr_sentinel = ptr_ptr_child_ty.sentinel();19977 ptr_sentinel = ptr_ptr_child_ty.sentinel();
...@@ -20162,6 +20170,12 @@ fn analyzeSlice(...@@ -20162,6 +20170,12 @@ fn analyzeSlice(
2016220170
20163 try sema.requireRuntimeBlock(block, src);20171 try sema.requireRuntimeBlock(block, src);
20164 if (block.wantSafety()) {20172 if (block.wantSafety()) {
20173 // requirement: slicing C ptr is non-null
20174 if (ptr_ptr_child_ty.isCPtr()) {
20175 const is_non_null = try sema.analyzeIsNull(block, ptr_src, ptr, true);
20176 try sema.addSafetyCheck(block, is_non_null, .unwrap_null);
20177 }
20178
20165 // requirement: end <= len20179 // requirement: end <= len
20166 const opt_len_inst = if (array_ty.zigTypeTag() == .Array)20180 const opt_len_inst = if (array_ty.zigTypeTag() == .Array)
20167 try sema.addIntUnsigned(Type.usize, array_ty.arrayLenIncludingSentinel())20181 try sema.addIntUnsigned(Type.usize, array_ty.arrayLenIncludingSentinel())
test/behavior/slice.zig+1
...@@ -233,6 +233,7 @@ fn sliceFromLenToLen(a_slice: []u8, start: usize, end: usize) []u8 {...@@ -233,6 +233,7 @@ fn sliceFromLenToLen(a_slice: []u8, start: usize, end: usize) []u8 {
233233
234test "C pointer" {234test "C pointer" {
235 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;235 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
236 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
236237
237 var buf: [*c]const u8 = "kjdhfkjdhfdkjhfkfjhdfkjdhfkdjhfdkjhf";238 var buf: [*c]const u8 = "kjdhfkjdhfdkjhfkfjhdfkjdhfkdjhfdkjhf";
238 var len: u32 = 10;239 var len: u32 = 10;
test/compile_errors/stage2/slice_of_null_pointer.zig created+10
...@@ -0,0 +1,10 @@
1comptime {
2 var x: [*c]u8 = null;
3 var runtime_len: usize = 0;
4 var y = x[0..runtime_len];
5 _ = y;
6}
7
8// slice of null C pointer
9//
10// :4:14: error: slice of null pointer