Skip to content

Commit 8796e7a

Browse files
committed
Auto merge of rust-lang#102315 - RalfJung:assert_unsafe_precondition, r=thomcc
add a few more assert_unsafe_precondition Add debug-assertion checking for `ptr.read()`, `ptr.write(_)`, and `unreachable_unchecked.` This is quite useful for [cargo-careful](https://github.com/RalfJung/cargo-careful).
2 parents c27948d + d71a851 commit 8796e7a

File tree

6 files changed

+14
-8
lines changed

6 files changed

+14
-8
lines changed

library/core/src/hint.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,10 @@ use crate::intrinsics;
100100
pub const unsafe fn unreachable_unchecked() -> ! {
101101
// SAFETY: the safety contract for `intrinsics::unreachable` must
102102
// be upheld by the caller.
103-
unsafe { intrinsics::unreachable() }
103+
unsafe {
104+
intrinsics::assert_unsafe_precondition!(() => false);
105+
intrinsics::unreachable()
106+
}
104107
}
105108

106109
/// Emits a machine instruction to signal the processor that it is running in

library/core/src/ptr/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1114,6 +1114,7 @@ pub const unsafe fn read<T>(src: *const T) -> T {
11141114
// Also, since we just wrote a valid value into `tmp`, it is guaranteed
11151115
// to be properly initialized.
11161116
unsafe {
1117+
assert_unsafe_precondition!([T](src: *const T) => is_aligned_and_not_null(src));
11171118
copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
11181119
tmp.assume_init()
11191120
}
@@ -1307,6 +1308,7 @@ pub const unsafe fn write<T>(dst: *mut T, src: T) {
13071308
// `dst` cannot overlap `src` because the caller has mutable access
13081309
// to `dst` while `src` is owned by this function.
13091310
unsafe {
1311+
assert_unsafe_precondition!([T](dst: *mut T) => is_aligned_and_not_null(dst));
13101312
copy_nonoverlapping(&src as *const T, dst, 1);
13111313
intrinsics::forget(src);
13121314
}

src/test/codegen/mem-replace-direct-memcpy.rs

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
// known to be `1` after inlining).
55

66
// compile-flags: -C no-prepopulate-passes -Zinline-mir=no
7+
// ignore-debug: the debug assertions get in the way
78

89
#![crate_type = "lib"]
910

src/test/ui/consts/const_unsafe_unreachable_ub.stderr

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error[E0080]: evaluation of constant value failed
22
--> $SRC_DIR/core/src/hint.rs:LL:COL
33
|
4-
LL | unsafe { intrinsics::unreachable() }
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^
6-
| |
7-
| entering unreachable code
8-
| inside `unreachable_unchecked` at $SRC_DIR/core/src/hint.rs:LL:COL
4+
LL | intrinsics::unreachable()
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
6+
| |
7+
| entering unreachable code
8+
| inside `unreachable_unchecked` at $SRC_DIR/core/src/hint.rs:LL:COL
99
|
1010
::: $DIR/const_unsafe_unreachable_ub.rs:6:18
1111
|

src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr1.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
fn main() {
55
// Try many times as this might work by chance.
6-
for _ in 0..10 {
6+
for _ in 0..20 {
77
let x = [2u16, 3, 4]; // Make it big enough so we don't get an out-of-bounds error.
88
let x = &x[0] as *const _ as *const u32;
99
// This must fail because alignment is violated: the allocation's base is not sufficiently aligned.

src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr_addr_of.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::ptr;
44

55
fn main() {
66
// Try many times as this might work by chance.
7-
for _ in 0..10 {
7+
for _ in 0..20 {
88
let x = [2u16, 3, 4]; // Make it big enough so we don't get an out-of-bounds error.
99
let x = &x[0] as *const _ as *const u32;
1010
// This must fail because alignment is violated: the allocation's base is not sufficiently aligned.

0 commit comments

Comments
 (0)