about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBen Kimock <kimockb@gmail.com>2024-10-07 19:34:25 -0400
committerBen Kimock <kimockb@gmail.com>2024-10-09 19:34:27 -0400
commit84dacc18829e24ec5d61087a233de68ef57dfabc (patch)
treedcafff34c26232cd7c2fddb27977e9060e221f31
parent0c41c3414c0e89ccb19310a4ec423ac83a48f039 (diff)
downloadrust-84dacc18829e24ec5d61087a233de68ef57dfabc.tar.gz
rust-84dacc18829e24ec5d61087a233de68ef57dfabc.zip
Add more precondition check tests
-rw-r--r--library/core/src/ascii/ascii_char.rs2
-rw-r--r--library/core/src/ptr/mod.rs6
-rw-r--r--tests/ui/precondition-checks/alignment.rs11
-rw-r--r--tests/ui/precondition-checks/ascii-char-digit_unchecked.rs11
-rw-r--r--tests/ui/precondition-checks/assert_unchecked.rs9
-rw-r--r--tests/ui/precondition-checks/char-from_u32_unchecked.rs9
-rw-r--r--tests/ui/precondition-checks/copy-nonoverlapping.rs25
-rw-r--r--tests/ui/precondition-checks/copy.rs23
-rw-r--r--tests/ui/precondition-checks/layout.rs15
-rw-r--r--tests/ui/precondition-checks/misaligned-slice.rs10
-rw-r--r--tests/ui/precondition-checks/nonnull.rs9
-rw-r--r--tests/ui/precondition-checks/nonzero-from_mut_unchecked.rs12
-rw-r--r--tests/ui/precondition-checks/nonzero-new_unchecked.rs9
-rw-r--r--tests/ui/precondition-checks/null-slice.rs10
-rw-r--r--tests/ui/precondition-checks/out-of-bounds-get-unchecked.rs11
-rw-r--r--tests/ui/precondition-checks/read.rs18
-rw-r--r--tests/ui/precondition-checks/read_volatile.rs17
-rw-r--r--tests/ui/precondition-checks/replace.rs17
-rw-r--r--tests/ui/precondition-checks/slice-from-raw-parts-mut.rs16
-rw-r--r--tests/ui/precondition-checks/slice-from-raw-parts.rs15
-rw-r--r--tests/ui/precondition-checks/slice-get_unchecked.rs20
-rw-r--r--tests/ui/precondition-checks/slice-get_unchecked_mut.rs20
-rw-r--r--tests/ui/precondition-checks/slice-swap_unchecked.rs14
-rw-r--r--tests/ui/precondition-checks/str-get_unchecked.rs18
-rw-r--r--tests/ui/precondition-checks/str-get_unchecked_mut.rs19
-rw-r--r--tests/ui/precondition-checks/swap-nonoverlapping.rs25
-rw-r--r--tests/ui/precondition-checks/unchecked_add.rs9
-rw-r--r--tests/ui/precondition-checks/unchecked_mul.rs9
-rw-r--r--tests/ui/precondition-checks/unchecked_shl.rs11
-rw-r--r--tests/ui/precondition-checks/unchecked_shr.rs11
-rw-r--r--tests/ui/precondition-checks/unchecked_sub.rs9
-rw-r--r--tests/ui/precondition-checks/unreachable_unchecked.rs9
-rw-r--r--tests/ui/precondition-checks/write.rs18
-rw-r--r--tests/ui/precondition-checks/write_bytes.rs18
-rw-r--r--tests/ui/precondition-checks/write_volatile.rs17
35 files changed, 448 insertions, 34 deletions
diff --git a/library/core/src/ascii/ascii_char.rs b/library/core/src/ascii/ascii_char.rs
index ce09a0b444d..48de4f17b1b 100644
--- a/library/core/src/ascii/ascii_char.rs
+++ b/library/core/src/ascii/ascii_char.rs
@@ -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
         );
 
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index 53ca5a7f198..62160937083 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -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)
     }
@@ -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)
     }
diff --git a/tests/ui/precondition-checks/alignment.rs b/tests/ui/precondition-checks/alignment.rs
new file mode 100644
index 00000000000..92400528fa0
--- /dev/null
+++ b/tests/ui/precondition-checks/alignment.rs
@@ -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);
+    }
+}
diff --git a/tests/ui/precondition-checks/ascii-char-digit_unchecked.rs b/tests/ui/precondition-checks/ascii-char-digit_unchecked.rs
new file mode 100644
index 00000000000..30c6f79fb08
--- /dev/null
+++ b/tests/ui/precondition-checks/ascii-char-digit_unchecked.rs
@@ -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');
+    }
+}
diff --git a/tests/ui/precondition-checks/assert_unchecked.rs b/tests/ui/precondition-checks/assert_unchecked.rs
new file mode 100644
index 00000000000..22b2b414550
--- /dev/null
+++ b/tests/ui/precondition-checks/assert_unchecked.rs
@@ -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);
+    }
+}
diff --git a/tests/ui/precondition-checks/char-from_u32_unchecked.rs b/tests/ui/precondition-checks/char-from_u32_unchecked.rs
new file mode 100644
index 00000000000..d950f20c772
--- /dev/null
+++ b/tests/ui/precondition-checks/char-from_u32_unchecked.rs
@@ -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);
+    }
+}
diff --git a/tests/ui/precondition-checks/copy-nonoverlapping.rs b/tests/ui/precondition-checks/copy-nonoverlapping.rs
new file mode 100644
index 00000000000..81018e4bff3
--- /dev/null
+++ b/tests/ui/precondition-checks/copy-nonoverlapping.rs
@@ -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);
+    }
+}
diff --git a/tests/ui/precondition-checks/copy.rs b/tests/ui/precondition-checks/copy.rs
new file mode 100644
index 00000000000..694853f950a
--- /dev/null
+++ b/tests/ui/precondition-checks/copy.rs
@@ -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);
+    }
+}
diff --git a/tests/ui/precondition-checks/layout.rs b/tests/ui/precondition-checks/layout.rs
new file mode 100644
index 00000000000..4fd1bbc4a99
--- /dev/null
+++ b/tests/ui/precondition-checks/layout.rs
@@ -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);
+    }
+}
diff --git a/tests/ui/precondition-checks/misaligned-slice.rs b/tests/ui/precondition-checks/misaligned-slice.rs
deleted file mode 100644
index 2963a0b5e63..00000000000
--- a/tests/ui/precondition-checks/misaligned-slice.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-//@ run-fail
-//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes
-//@ error-pattern: unsafe precondition(s) violated: slice::from_raw_parts
-//@ ignore-debug
-
-fn main() {
-    unsafe {
-        let _s: &[u64] = std::slice::from_raw_parts(1usize as *const u64, 0);
-    }
-}
diff --git a/tests/ui/precondition-checks/nonnull.rs b/tests/ui/precondition-checks/nonnull.rs
new file mode 100644
index 00000000000..6b8edd4e582
--- /dev/null
+++ b/tests/ui/precondition-checks/nonnull.rs
@@ -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>());
+    }
+}
diff --git a/tests/ui/precondition-checks/nonzero-from_mut_unchecked.rs b/tests/ui/precondition-checks/nonzero-from_mut_unchecked.rs
new file mode 100644
index 00000000000..46ce7dc356f
--- /dev/null
+++ b/tests/ui/precondition-checks/nonzero-from_mut_unchecked.rs
@@ -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);
+    }
+}
diff --git a/tests/ui/precondition-checks/nonzero-new_unchecked.rs b/tests/ui/precondition-checks/nonzero-new_unchecked.rs
new file mode 100644
index 00000000000..7827a42844f
--- /dev/null
+++ b/tests/ui/precondition-checks/nonzero-new_unchecked.rs
@@ -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);
+    }
+}
diff --git a/tests/ui/precondition-checks/null-slice.rs b/tests/ui/precondition-checks/null-slice.rs
deleted file mode 100644
index 280960358b7..00000000000
--- a/tests/ui/precondition-checks/null-slice.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-//@ run-fail
-//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes
-//@ error-pattern: unsafe precondition(s) violated: slice::from_raw_parts
-//@ ignore-debug
-
-fn main() {
-    unsafe {
-        let _s: &[u8] = std::slice::from_raw_parts(std::ptr::null(), 0);
-    }
-}
diff --git a/tests/ui/precondition-checks/out-of-bounds-get-unchecked.rs b/tests/ui/precondition-checks/out-of-bounds-get-unchecked.rs
deleted file mode 100644
index 011e92183fa..00000000000
--- a/tests/ui/precondition-checks/out-of-bounds-get-unchecked.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-//@ run-fail
-//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes
-//@ error-pattern: slice::get_unchecked requires
-//@ ignore-debug
-
-fn main() {
-    unsafe {
-        let sli: &[u8] = &[0];
-        sli.get_unchecked(1);
-    }
-}
diff --git a/tests/ui/precondition-checks/read.rs b/tests/ui/precondition-checks/read.rs
new file mode 100644
index 00000000000..ab9921a0cee
--- /dev/null
+++ b/tests/ui/precondition-checks/read.rs
@@ -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));
+    }
+}
diff --git a/tests/ui/precondition-checks/read_volatile.rs b/tests/ui/precondition-checks/read_volatile.rs
new file mode 100644
index 00000000000..e14881d0290
--- /dev/null
+++ b/tests/ui/precondition-checks/read_volatile.rs
@@ -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));
+    }
+}
diff --git a/tests/ui/precondition-checks/replace.rs b/tests/ui/precondition-checks/replace.rs
new file mode 100644
index 00000000000..2808cee7b64
--- /dev/null
+++ b/tests/ui/precondition-checks/replace.rs
@@ -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);
+    }
+}
diff --git a/tests/ui/precondition-checks/slice-from-raw-parts-mut.rs b/tests/ui/precondition-checks/slice-from-raw-parts-mut.rs
new file mode 100644
index 00000000000..3801639e255
--- /dev/null
+++ b/tests/ui/precondition-checks/slice-from-raw-parts-mut.rs
@@ -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);
+    }
+}
diff --git a/tests/ui/precondition-checks/slice-from-raw-parts.rs b/tests/ui/precondition-checks/slice-from-raw-parts.rs
new file mode 100644
index 00000000000..a3690fa045e
--- /dev/null
+++ b/tests/ui/precondition-checks/slice-from-raw-parts.rs
@@ -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);
+    }
+}
diff --git a/tests/ui/precondition-checks/slice-get_unchecked.rs b/tests/ui/precondition-checks/slice-get_unchecked.rs
new file mode 100644
index 00000000000..1d8188fb953
--- /dev/null
+++ b/tests/ui/precondition-checks/slice-get_unchecked.rs
@@ -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);
+     }
+}
diff --git a/tests/ui/precondition-checks/slice-get_unchecked_mut.rs b/tests/ui/precondition-checks/slice-get_unchecked_mut.rs
new file mode 100644
index 00000000000..34c1454af43
--- /dev/null
+++ b/tests/ui/precondition-checks/slice-get_unchecked_mut.rs
@@ -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);
+     }
+}
diff --git a/tests/ui/precondition-checks/slice-swap_unchecked.rs b/tests/ui/precondition-checks/slice-swap_unchecked.rs
new file mode 100644
index 00000000000..227a49091ec
--- /dev/null
+++ b/tests/ui/precondition-checks/slice-swap_unchecked.rs
@@ -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);
+    }
+}
diff --git a/tests/ui/precondition-checks/str-get_unchecked.rs b/tests/ui/precondition-checks/str-get_unchecked.rs
new file mode 100644
index 00000000000..14d17f997ec
--- /dev/null
+++ b/tests/ui/precondition-checks/str-get_unchecked.rs
@@ -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);
+    }
+}
diff --git a/tests/ui/precondition-checks/str-get_unchecked_mut.rs b/tests/ui/precondition-checks/str-get_unchecked_mut.rs
new file mode 100644
index 00000000000..ca1b1690055
--- /dev/null
+++ b/tests/ui/precondition-checks/str-get_unchecked_mut.rs
@@ -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);
+    }
+}
diff --git a/tests/ui/precondition-checks/swap-nonoverlapping.rs b/tests/ui/precondition-checks/swap-nonoverlapping.rs
new file mode 100644
index 00000000000..52e4a3c870b
--- /dev/null
+++ b/tests/ui/precondition-checks/swap-nonoverlapping.rs
@@ -0,0 +1,25 @@
+//@ run-fail
+//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes
+//@ error-pattern: unsafe precondition(s) violated: ptr::swap_nonoverlapping requires
+//@ revisions: null_src null_dst misaligned_src misaligned_dst overlapping
+
+use std::ptr;
+
+fn main() {
+    let mut src = [0u16; 3];
+    let mut dst = [0u16; 3];
+    let src = src.as_mut_ptr();
+    let dst = dst.as_mut_ptr();
+    unsafe {
+        #[cfg(null_src)]
+        ptr::swap_nonoverlapping(ptr::null_mut(), dst, 1);
+        #[cfg(null_dst)]
+        ptr::swap_nonoverlapping(src, ptr::null_mut(), 1);
+        #[cfg(misaligned_src)]
+        ptr::swap_nonoverlapping(src.byte_add(1), dst, 1);
+        #[cfg(misaligned_dst)]
+        ptr::swap_nonoverlapping(src, dst.byte_add(1), 1);
+        #[cfg(overlapping)]
+        ptr::swap_nonoverlapping(dst, dst.add(1), 2);
+    }
+}
diff --git a/tests/ui/precondition-checks/unchecked_add.rs b/tests/ui/precondition-checks/unchecked_add.rs
new file mode 100644
index 00000000000..f44a6ea32ad
--- /dev/null
+++ b/tests/ui/precondition-checks/unchecked_add.rs
@@ -0,0 +1,9 @@
+//@ run-fail
+//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes
+//@ error-pattern: unsafe precondition(s) violated: u8::unchecked_add cannot overflow
+
+fn main() {
+    unsafe {
+        1u8.unchecked_add(u8::MAX);
+    }
+}
diff --git a/tests/ui/precondition-checks/unchecked_mul.rs b/tests/ui/precondition-checks/unchecked_mul.rs
new file mode 100644
index 00000000000..66655dda136
--- /dev/null
+++ b/tests/ui/precondition-checks/unchecked_mul.rs
@@ -0,0 +1,9 @@
+//@ run-fail
+//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes
+//@ error-pattern: unsafe precondition(s) violated: u8::unchecked_add cannot overflow
+
+fn main() {
+    unsafe {
+        2u8.unchecked_add(u8::MAX);
+    }
+}
diff --git a/tests/ui/precondition-checks/unchecked_shl.rs b/tests/ui/precondition-checks/unchecked_shl.rs
new file mode 100644
index 00000000000..1c96db0b1ec
--- /dev/null
+++ b/tests/ui/precondition-checks/unchecked_shl.rs
@@ -0,0 +1,11 @@
+//@ run-fail
+//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes
+//@ error-pattern: unsafe precondition(s) violated: u8::unchecked_shl cannot overflow
+
+#![feature(unchecked_shifts)]
+
+fn main() {
+    unsafe {
+        0u8.unchecked_shl(u8::BITS);
+    }
+}
diff --git a/tests/ui/precondition-checks/unchecked_shr.rs b/tests/ui/precondition-checks/unchecked_shr.rs
new file mode 100644
index 00000000000..4a6d9ffb1d3
--- /dev/null
+++ b/tests/ui/precondition-checks/unchecked_shr.rs
@@ -0,0 +1,11 @@
+//@ run-fail
+//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes
+//@ error-pattern: unsafe precondition(s) violated: u8::unchecked_shr cannot overflow
+
+#![feature(unchecked_shifts)]
+
+fn main() {
+    unsafe {
+        0u8.unchecked_shr(u8::BITS);
+    }
+}
diff --git a/tests/ui/precondition-checks/unchecked_sub.rs b/tests/ui/precondition-checks/unchecked_sub.rs
new file mode 100644
index 00000000000..545dde0e278
--- /dev/null
+++ b/tests/ui/precondition-checks/unchecked_sub.rs
@@ -0,0 +1,9 @@
+//@ run-fail
+//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes
+//@ error-pattern: unsafe precondition(s) violated: u8::unchecked_sub cannot overflow
+
+fn main() {
+    unsafe {
+        0u8.unchecked_sub(1u8);
+    }
+}
diff --git a/tests/ui/precondition-checks/unreachable_unchecked.rs b/tests/ui/precondition-checks/unreachable_unchecked.rs
new file mode 100644
index 00000000000..2435450c4b5
--- /dev/null
+++ b/tests/ui/precondition-checks/unreachable_unchecked.rs
@@ -0,0 +1,9 @@
+//@ run-fail
+//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes
+//@ error-pattern: unsafe precondition(s) violated: hint::unreachable_unchecked must never be reached
+
+fn main() {
+    unsafe {
+        std::hint::unreachable_unchecked();
+    }
+}
diff --git a/tests/ui/precondition-checks/write.rs b/tests/ui/precondition-checks/write.rs
new file mode 100644
index 00000000000..f76e776fcf3
--- /dev/null
+++ b/tests/ui/precondition-checks/write.rs
@@ -0,0 +1,18 @@
+//@ run-fail
+//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes
+//@ error-pattern: unsafe precondition(s) violated: ptr::write requires
+//@ revisions: null misaligned
+//@ ignore-test
+
+use std::ptr;
+
+fn main() {
+    let mut dst = [0u16; 2];
+    let mut dst = dst.as_mut_ptr();
+    unsafe {
+        #[cfg(null)]
+        ptr::write(ptr::null_mut::<u8>(), 1u8);
+        #[cfg(misaligned)]
+        ptr::write(dst.byte_add(1), 1u16);
+    }
+}
diff --git a/tests/ui/precondition-checks/write_bytes.rs b/tests/ui/precondition-checks/write_bytes.rs
new file mode 100644
index 00000000000..3f64be9d1ee
--- /dev/null
+++ b/tests/ui/precondition-checks/write_bytes.rs
@@ -0,0 +1,18 @@
+//@ run-fail
+//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes
+//@ error-pattern: unsafe precondition(s) violated: ptr::write requires
+//@ revisions: null misaligned
+//@ ignore-test
+
+use std::ptr;
+
+fn main() {
+    let mut dst = [0u16; 2];
+    let mut dst = dst.as_mut_ptr();
+    unsafe {
+        #[cfg(null)]
+        ptr::write_bytes(ptr::null_mut::<u8>(), 1u8, 2);
+        #[cfg(misaligned)]
+        ptr::write_bytes(dst.byte_add(1), 1u8, 2);
+    }
+}
diff --git a/tests/ui/precondition-checks/write_volatile.rs b/tests/ui/precondition-checks/write_volatile.rs
new file mode 100644
index 00000000000..ac0b89b5ecf
--- /dev/null
+++ b/tests/ui/precondition-checks/write_volatile.rs
@@ -0,0 +1,17 @@
+//@ run-fail
+//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes
+//@ error-pattern: unsafe precondition(s) violated: ptr::write_volatile requires
+//@ revisions: null misaligned
+
+use std::ptr;
+
+fn main() {
+    let mut dst = [0u16; 2];
+    let mut dst = dst.as_mut_ptr();
+    unsafe {
+        #[cfg(null)]
+        ptr::write_volatile(ptr::null_mut::<u8>(), 1u8);
+        #[cfg(misaligned)]
+        ptr::write_volatile(dst.byte_add(1), 1u16);
+    }
+}