Skip to content

Commit

Permalink
Add more precondition check tests
Browse files Browse the repository at this point in the history
  • Loading branch information
saethlin committed Oct 9, 2024
1 parent 8413ddc commit b1fe718
Show file tree
Hide file tree
Showing 35 changed files with 448 additions and 34 deletions.
2 changes: 1 addition & 1 deletion library/core/src/ascii/ascii_char.rs
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,7 @@ impl AsciiChar {
pub const unsafe fn digit_unchecked(d: u8) -> Self {
assert_unsafe_precondition!(
check_language_ub,
"`AsciiChar::digit_unchecked` input cannot exceed 9.",
"`ascii::Char::digit_unchecked` input cannot exceed 9.",
(d: u8 = d) => d < 10
);

Expand Down
6 changes: 4 additions & 2 deletions library/core/src/ptr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1432,7 +1432,8 @@ pub const unsafe fn read<T>(src: *const T) -> T {
(
addr: *const () = src as *const (),
align: usize = align_of::<T>(),
) => ub_checks::is_aligned_and_not_null(addr, align)
is_zst: bool = T::IS_ZST,
) => ub_checks::is_aligned_and_not_null(addr, align, is_zst)
);
crate::intrinsics::read_via_copy(src)
}
Expand Down Expand Up @@ -1637,7 +1638,8 @@ pub const unsafe fn write<T>(dst: *mut T, src: T) {
(
addr: *mut () = dst as *mut (),
align: usize = align_of::<T>(),
) => ub_checks::is_aligned_and_not_null(addr, align)
is_zst: bool = T::IS_ZST,
) => ub_checks::is_aligned_and_not_null(addr, align, is_zst)
);
intrinsics::write_via_move(dst, src)
}
Expand Down
11 changes: 11 additions & 0 deletions tests/ui/precondition-checks/alignment.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//@ run-fail
//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes
//@ error-pattern: unsafe precondition(s) violated: Alignment::new_unchecked requires

#![feature(ptr_alignment_type)]

fn main() {
unsafe {
std::ptr::Alignment::new_unchecked(0);
}
}
11 changes: 11 additions & 0 deletions tests/ui/precondition-checks/ascii-char-digit_unchecked.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//@ run-fail
//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes
//@ error-pattern: unsafe precondition(s) violated: `ascii::Char::digit_unchecked` input cannot exceed 9

#![feature(ascii_char)]

fn main() {
unsafe {
std::ascii::Char::digit_unchecked(b'a');
}
}
9 changes: 9 additions & 0 deletions tests/ui/precondition-checks/assert_unchecked.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//@ run-fail
//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes
//@ error-pattern: unsafe precondition(s) violated: hint::assert_unchecked must never be called when the condition is false

fn main() {
unsafe {
std::hint::assert_unchecked(false);
}
}
9 changes: 9 additions & 0 deletions tests/ui/precondition-checks/char-from_u32_unchecked.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//@ run-fail
//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes
//@ error-pattern: unsafe precondition(s) violated: invalid value for `char`

fn main() {
unsafe {
char::from_u32_unchecked(0xD801);
}
}
25 changes: 25 additions & 0 deletions tests/ui/precondition-checks/copy-nonoverlapping.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//@ run-fail
//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes
//@ error-pattern: unsafe precondition(s) violated: ptr::copy_nonoverlapping requires
//@ revisions: null_src null_dst misaligned_src misaligned_dst overlapping

use std::ptr;

fn main() {
let src = [0u16; 3];
let mut dst = [0u16; 3];
let src = src.as_ptr();
let dst = dst.as_mut_ptr();
unsafe {
#[cfg(null_src)]
ptr::copy_nonoverlapping(ptr::null(), dst, 1);
#[cfg(null_dst)]
ptr::copy_nonoverlapping(src, ptr::null_mut(), 1);
#[cfg(misaligned_src)]
ptr::copy_nonoverlapping(src.byte_add(1), dst, 1);
#[cfg(misaligned_dst)]
ptr::copy_nonoverlapping(src, dst.byte_add(1), 1);
#[cfg(overlapping)]
ptr::copy_nonoverlapping(dst, dst.add(1), 2);
}
}
23 changes: 23 additions & 0 deletions tests/ui/precondition-checks/copy.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//@ run-fail
//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes
//@ error-pattern: unsafe precondition(s) violated: ptr::copy requires
//@ revisions: null_src null_dst misaligned_src misaligned_dst

use std::ptr;

fn main() {
let src = [0u16; 3];
let mut dst = [0u16; 3];
let src = src.as_ptr();
let dst = dst.as_mut_ptr();
unsafe {
#[cfg(null_src)]
ptr::copy(ptr::null(), dst, 1);
#[cfg(null_dst)]
ptr::copy(src, ptr::null_mut(), 1);
#[cfg(misaligned_src)]
ptr::copy(src.byte_add(1), dst, 1);
#[cfg(misaligned_dst)]
ptr::copy(src, dst.byte_add(1), 1);
}
}
15 changes: 15 additions & 0 deletions tests/ui/precondition-checks/layout.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//@ run-fail
//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes
//@ error-pattern: unsafe precondition(s) violated: Layout::from_size_align_unchecked requires
//@ revisions: toolarge badalign
//@[toolarge] compile-flags: --cfg toolarge
//@[badalign] compile-flags: --cfg badalign

fn main() {
unsafe {
#[cfg(toolarge)]
std::alloc::Layout::from_size_align_unchecked(isize::MAX as usize, 2);
#[cfg(badalign)]
std::alloc::Layout::from_size_align_unchecked(1, 3);
}
}
10 changes: 0 additions & 10 deletions tests/ui/precondition-checks/misaligned-slice.rs

This file was deleted.

9 changes: 9 additions & 0 deletions tests/ui/precondition-checks/nonnull.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//@ run-fail
//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes
//@ error-pattern: unsafe precondition(s) violated: NonNull::new_unchecked requires

fn main() {
unsafe {
std::ptr::NonNull::new_unchecked(std::ptr::null_mut::<u8>());
}
}
12 changes: 12 additions & 0 deletions tests/ui/precondition-checks/nonzero-from_mut_unchecked.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//@ run-fail
//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes
//@ error-pattern: unsafe precondition(s) violated: NonZero::from_mut_unchecked requires

#![feature(nonzero_from_mut)]

fn main() {
unsafe {
let mut num = 0u8;
std::num::NonZeroU8::from_mut_unchecked(&mut num);
}
}
9 changes: 9 additions & 0 deletions tests/ui/precondition-checks/nonzero-new_unchecked.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//@ run-fail
//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes
//@ error-pattern: unsafe precondition(s) violated: NonZero::new_unchecked requires

fn main() {
unsafe {
std::num::NonZeroU8::new_unchecked(0);
}
}
10 changes: 0 additions & 10 deletions tests/ui/precondition-checks/null-slice.rs

This file was deleted.

11 changes: 0 additions & 11 deletions tests/ui/precondition-checks/out-of-bounds-get-unchecked.rs

This file was deleted.

18 changes: 18 additions & 0 deletions tests/ui/precondition-checks/read.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//@ run-fail
//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes
//@ error-pattern: unsafe precondition(s) violated: ptr::read requires
//@ revisions: null misaligned
//@ ignore-test

use std::ptr;

fn main() {
let src = [0u16; 2];
let src = src.as_ptr();
unsafe {
#[cfg(null)]
ptr::read(ptr::null::<u8>());
#[cfg(misaligned)]
ptr::read(src.byte_add(1));
}
}
17 changes: 17 additions & 0 deletions tests/ui/precondition-checks/read_volatile.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//@ run-fail
//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes
//@ error-pattern: unsafe precondition(s) violated: ptr::read_volatile requires
//@ revisions: null misaligned

use std::ptr;

fn main() {
let src = [0u16; 2];
let src = src.as_ptr();
unsafe {
#[cfg(null)]
ptr::read_volatile(ptr::null::<u8>());
#[cfg(misaligned)]
ptr::read_volatile(src.byte_add(1));
}
}
17 changes: 17 additions & 0 deletions tests/ui/precondition-checks/replace.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//@ run-fail
//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes
//@ error-pattern: unsafe precondition(s) violated: ptr::replace requires
//@ revisions: null misaligned

use std::ptr;

fn main() {
let mut dst = [0u16; 2];
let dst = dst.as_mut_ptr();
unsafe {
#[cfg(null)]
ptr::replace(ptr::null_mut::<u8>(), 1);
#[cfg(misaligned)]
ptr::replace(dst.byte_add(1), 1u16);
}
}
16 changes: 16 additions & 0 deletions tests/ui/precondition-checks/slice-from-raw-parts-mut.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//@ run-fail
//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes
//@ error-pattern: unsafe precondition(s) violated: slice::from_raw_parts_mut requires
//@ revisions: null misaligned toolarge

fn main() {
unsafe {
#[cfg(null)]
let _s: &mut [u8] = std::slice::from_raw_parts_mut(std::ptr::null_mut(), 0);
#[cfg(misaligned)]
let _s: &mut [u16] = std::slice::from_raw_parts_mut(1usize as *mut u16, 0);
#[cfg(toolarge)]
let _s: &mut [u16] =
std::slice::from_raw_parts_mut(2usize as *mut u16, isize::MAX as usize);
}
}
15 changes: 15 additions & 0 deletions tests/ui/precondition-checks/slice-from-raw-parts.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//@ run-fail
//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes
//@ error-pattern: unsafe precondition(s) violated: slice::from_raw_parts requires
//@ revisions: null misaligned toolarge

fn main() {
unsafe {
#[cfg(null)]
let _s: &[u8] = std::slice::from_raw_parts(std::ptr::null(), 0);
#[cfg(misaligned)]
let _s: &[u16] = std::slice::from_raw_parts(1usize as *const u16, 0);
#[cfg(toolarge)]
let _s: &[u16] = std::slice::from_raw_parts(2usize as *const u16, isize::MAX as usize);
}
}
20 changes: 20 additions & 0 deletions tests/ui/precondition-checks/slice-get_unchecked.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//@ run-fail
//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes
//@ error-pattern: unsafe precondition(s) violated: slice::get_unchecked requires
//@ revisions: usize range range_to range_from backwards_range

fn main() {
unsafe {
let s = &[0];
#[cfg(usize)]
s.get_unchecked(1);
#[cfg(range)]
s.get_unchecked(1..2);
#[cfg(range_to)]
s.get_unchecked(..2);
#[cfg(range_from)]
s.get_unchecked(2..);
#[cfg(backwards_range)]
s.get_unchecked(1..0);
}
}
20 changes: 20 additions & 0 deletions tests/ui/precondition-checks/slice-get_unchecked_mut.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//@ run-fail
//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes
//@ error-pattern: unsafe precondition(s) violated: slice::get_unchecked_mut requires
//@ revisions: usize range range_to range_from backwards_range

fn main() {
unsafe {
let mut s = &mut [0];
#[cfg(usize)]
s.get_unchecked_mut(1);
#[cfg(range)]
s.get_unchecked_mut(1..2);
#[cfg(range_to)]
s.get_unchecked_mut(..2);
#[cfg(range_from)]
s.get_unchecked_mut(2..);
#[cfg(backwards_range)]
s.get_unchecked_mut(1..0);
}
}
14 changes: 14 additions & 0 deletions tests/ui/precondition-checks/slice-swap_unchecked.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//@ run-fail
//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes
//@ error-pattern: index out of bounds: the len is 2 but the index is 2
//@ revisions: oob_a oob_b

fn main() {
let mut pair = [0u8; 2];
unsafe {
#[cfg(oob_a)]
pair.swap(0, 2);
#[cfg(oob_b)]
pair.swap(2, 0);
}
}
18 changes: 18 additions & 0 deletions tests/ui/precondition-checks/str-get_unchecked.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//@ run-fail
//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes
//@ error-pattern: unsafe precondition(s) violated: str::get_unchecked requires
//@ revisions: range range_to range_from backwards_range

fn main() {
unsafe {
let s = "💅";
#[cfg(range)]
s.get_unchecked(4..5);
#[cfg(range_to)]
s.get_unchecked(..5);
#[cfg(range_from)]
s.get_unchecked(5..);
#[cfg(backwards_range)]
s.get_unchecked(1..0);
}
}
19 changes: 19 additions & 0 deletions tests/ui/precondition-checks/str-get_unchecked_mut.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//@ run-fail
//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes
//@ error-pattern: unsafe precondition(s) violated: str::get_unchecked_mut requires
//@ revisions: range range_to range_from backwards_range

fn main() {
unsafe {
let mut s: String = "💅".chars().collect();
let mut s: &mut str = &mut s;
#[cfg(range)]
s.get_unchecked_mut(4..5);
#[cfg(range_to)]
s.get_unchecked_mut(..5);
#[cfg(range_from)]
s.get_unchecked_mut(5..);
#[cfg(backwards_range)]
s.get_unchecked_mut(1..0);
}
}
Loading

0 comments on commit b1fe718

Please sign in to comment.