diff --git a/src/Sema.zig b/src/Sema.zig index 4e0b57fbc6..86e330a759 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -19964,6 +19964,14 @@ fn analyzeSlice( slice_ty = ptr_ptr_child_ty; array_ty = ptr_ptr_child_ty; elem_ty = ptr_ptr_child_ty.childType(); + + if (ptr_ptr_child_ty.ptrSize() == .C) { + if (try sema.resolveDefinedValue(block, ptr_src, ptr_or_slice)) |ptr_val| { + if (ptr_val.isNull()) { + return sema.fail(block, ptr_src, "slice of null pointer", .{}); + } + } + } }, .Slice => { ptr_sentinel = ptr_ptr_child_ty.sentinel(); @@ -20162,6 +20170,12 @@ fn analyzeSlice( try sema.requireRuntimeBlock(block, src); if (block.wantSafety()) { + // requirement: slicing C ptr is non-null + if (ptr_ptr_child_ty.isCPtr()) { + const is_non_null = try sema.analyzeIsNull(block, ptr_src, ptr, true); + try sema.addSafetyCheck(block, is_non_null, .unwrap_null); + } + // requirement: end <= len const opt_len_inst = if (array_ty.zigTypeTag() == .Array) try sema.addIntUnsigned(Type.usize, array_ty.arrayLenIncludingSentinel()) diff --git a/test/behavior/slice.zig b/test/behavior/slice.zig index 9f3ba001cf..a9f89130a1 100644 --- a/test/behavior/slice.zig +++ b/test/behavior/slice.zig @@ -233,6 +233,7 @@ fn sliceFromLenToLen(a_slice: []u8, start: usize, end: usize) []u8 { test "C pointer" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; var buf: [*c]const u8 = "kjdhfkjdhfdkjhfkfjhdfkjdhfkdjhfdkjhf"; var len: u32 = 10; diff --git a/test/compile_errors/stage2/slice_of_null_pointer.zig b/test/compile_errors/stage2/slice_of_null_pointer.zig new file mode 100644 index 0000000000..1e3f0d6aee --- /dev/null +++ b/test/compile_errors/stage2/slice_of_null_pointer.zig @@ -0,0 +1,10 @@ +comptime { + var x: [*c]u8 = null; + var runtime_len: usize = 0; + var y = x[0..runtime_len]; + _ = y; +} + +// slice of null C pointer +// +// :4:14: error: slice of null pointer