about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2020-06-19 14:29:24 +0200
committerGitHub <noreply@github.com>2020-06-19 14:29:24 +0200
commit125c196bca6f144c5f6a97b725b715dd0964c3d5 (patch)
treeeb381b65ce8a97b9916df9b18778f966fb644a74
parent0851036ae30efa58b47258ad3b718d6ef66dc706 (diff)
parent81c7ebd54418fe2f91be10b7371c7a3f5cca3771 (diff)
downloadrust-125c196bca6f144c5f6a97b725b715dd0964c3d5.tar.gz
rust-125c196bca6f144c5f6a97b725b715dd0964c3d5.zip
Rollup merge of #73054 - RalfJung:dont-panic, r=Mark-Simulacrum
memory access sanity checks: abort instead of panic

Suggested by @Mark-Simulacrum, this should help reduce the performance impact of these checks.
-rw-r--r--src/libcore/intrinsics.rs17
-rw-r--r--src/libcore/ptr/mod.rs28
-rw-r--r--src/test/codegen/vec-clear.rs1
-rw-r--r--src/test/codegen/vec-optimizes-away.rs1
4 files changed, 33 insertions, 14 deletions
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index 2d3e1814661..9061145a695 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -2064,9 +2064,14 @@ pub unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize) {
         fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
     }
 
-    debug_assert!(is_aligned_and_not_null(src), "attempt to copy from unaligned or null pointer");
-    debug_assert!(is_aligned_and_not_null(dst), "attempt to copy to unaligned or null pointer");
-    debug_assert!(is_nonoverlapping(src, dst, count), "attempt to copy to overlapping memory");
+    if cfg!(debug_assertions)
+        && !(is_aligned_and_not_null(src)
+            && is_aligned_and_not_null(dst)
+            && is_nonoverlapping(src, dst, count))
+    {
+        // Not panicking to keep codegen impact smaller.
+        abort();
+    }
     copy_nonoverlapping(src, dst, count)
 }
 
@@ -2129,8 +2134,10 @@ pub unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
         fn copy<T>(src: *const T, dst: *mut T, count: usize);
     }
 
-    debug_assert!(is_aligned_and_not_null(src), "attempt to copy from unaligned or null pointer");
-    debug_assert!(is_aligned_and_not_null(dst), "attempt to copy to unaligned or null pointer");
+    if cfg!(debug_assertions) && !(is_aligned_and_not_null(src) && is_aligned_and_not_null(dst)) {
+        // Not panicking to keep codegen impact smaller.
+        abort();
+    }
     copy(src, dst, count)
 }
 
diff --git a/src/libcore/ptr/mod.rs b/src/libcore/ptr/mod.rs
index 172b23a8d5a..ca2b0c85ec1 100644
--- a/src/libcore/ptr/mod.rs
+++ b/src/libcore/ptr/mod.rs
@@ -70,7 +70,7 @@
 use crate::cmp::Ordering;
 use crate::fmt;
 use crate::hash;
-use crate::intrinsics::{self, is_aligned_and_not_null, is_nonoverlapping};
+use crate::intrinsics::{self, abort, is_aligned_and_not_null, is_nonoverlapping};
 use crate::mem::{self, MaybeUninit};
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -420,9 +420,14 @@ pub unsafe fn swap<T>(x: *mut T, y: *mut T) {
 #[inline]
 #[stable(feature = "swap_nonoverlapping", since = "1.27.0")]
 pub unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) {
-    debug_assert!(is_aligned_and_not_null(x), "attempt to swap unaligned or null pointer");
-    debug_assert!(is_aligned_and_not_null(y), "attempt to swap unaligned or null pointer");
-    debug_assert!(is_nonoverlapping(x, y, count), "attempt to swap overlapping memory");
+    if cfg!(debug_assertions)
+        && !(is_aligned_and_not_null(x)
+            && is_aligned_and_not_null(y)
+            && is_nonoverlapping(x, y, count))
+    {
+        // Not panicking to keep codegen impact smaller.
+        abort();
+    }
 
     let x = x as *mut u8;
     let y = y as *mut u8;
@@ -838,7 +843,10 @@ pub unsafe fn read_unaligned<T>(src: *const T) -> T {
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub unsafe fn write<T>(dst: *mut T, src: T) {
-    debug_assert!(is_aligned_and_not_null(dst), "attempt to write to unaligned or null pointer");
+    if cfg!(debug_assertions) && !is_aligned_and_not_null(dst) {
+        // Not panicking to keep codegen impact smaller.
+        abort();
+    }
     intrinsics::move_val_init(&mut *dst, src)
 }
 
@@ -1003,7 +1011,10 @@ pub unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
 #[inline]
 #[stable(feature = "volatile", since = "1.9.0")]
 pub unsafe fn read_volatile<T>(src: *const T) -> T {
-    debug_assert!(is_aligned_and_not_null(src), "attempt to read from unaligned or null pointer");
+    if cfg!(debug_assertions) && !is_aligned_and_not_null(src) {
+        // Not panicking to keep codegen impact smaller.
+        abort();
+    }
     intrinsics::volatile_load(src)
 }
 
@@ -1072,7 +1083,10 @@ pub unsafe fn read_volatile<T>(src: *const T) -> T {
 #[inline]
 #[stable(feature = "volatile", since = "1.9.0")]
 pub unsafe fn write_volatile<T>(dst: *mut T, src: T) {
-    debug_assert!(is_aligned_and_not_null(dst), "attempt to write to unaligned or null pointer");
+    if cfg!(debug_assertions) && !is_aligned_and_not_null(dst) {
+        // Not panicking to keep codegen impact smaller.
+        abort();
+    }
     intrinsics::volatile_store(dst, src);
 }
 
diff --git a/src/test/codegen/vec-clear.rs b/src/test/codegen/vec-clear.rs
index b9ffce8b0cb..15bfe421e9d 100644
--- a/src/test/codegen/vec-clear.rs
+++ b/src/test/codegen/vec-clear.rs
@@ -1,4 +1,3 @@
-// ignore-debug: the debug assertions get in the way
 // compile-flags: -O
 
 #![crate_type = "lib"]
diff --git a/src/test/codegen/vec-optimizes-away.rs b/src/test/codegen/vec-optimizes-away.rs
index ebede0908c6..9143fad2340 100644
--- a/src/test/codegen/vec-optimizes-away.rs
+++ b/src/test/codegen/vec-optimizes-away.rs
@@ -1,4 +1,3 @@
-//
 // ignore-debug: the debug assertions get in the way
 // no-system-llvm
 // compile-flags: -O