about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2022-11-25 10:44:38 +0100
committerGitHub <noreply@github.com>2022-11-25 10:44:38 +0100
commit808157bd7dd9d1b082c674e9581e18266c7501f0 (patch)
treedfeed100c427a97a9ca908fa5518096fd38d76f0
parenta9313e9077aa594afe80da8e423de614cada9040 (diff)
parent54a6d4edbc56d99ecf6a461975acceb219b8a2d8 (diff)
downloadrust-808157bd7dd9d1b082c674e9581e18266c7501f0.tar.gz
rust-808157bd7dd9d1b082c674e9581e18266c7501f0.zip
Rollup merge of #104654 - thomcc:alloc-tests-unsafe_op_in_unsafe_fn, r=Mark-Simulacrum
Add `#![deny(unsafe_op_in_unsafe_fn)]` in liballoc tests

In https://github.com/rust-lang/rust/pull/104647#discussion_r1027332930 it was mentioned that liballoc tests should probably have this enabled (we have it pretty much everywhere else in the stdlib), so I added it.

This will probably conflict with https://github.com/rust-lang/rust/pull/104647 so I'll rebase after that lands.
-rw-r--r--library/alloc/tests/boxed.rs41
-rw-r--r--library/alloc/tests/lib.rs1
-rw-r--r--library/alloc/tests/vec.rs3
3 files changed, 38 insertions, 7 deletions
diff --git a/library/alloc/tests/boxed.rs b/library/alloc/tests/boxed.rs
index 9e5123be989..af49826ff30 100644
--- a/library/alloc/tests/boxed.rs
+++ b/library/alloc/tests/boxed.rs
@@ -102,8 +102,18 @@ unsafe impl const Allocator for ConstAllocator {
 
         let new_ptr = self.allocate(new_layout)?;
         if new_layout.size() > 0 {
-            new_ptr.as_mut_ptr().copy_from_nonoverlapping(ptr.as_ptr(), old_layout.size());
-            self.deallocate(ptr, old_layout);
+            // Safety: `new_ptr` is valid for writes and `ptr` for reads of
+            // `old_layout.size()`, because `new_layout.size() >=
+            // old_layout.size()` (which is an invariant that must be upheld by
+            // callers).
+            unsafe {
+                new_ptr.as_mut_ptr().copy_from_nonoverlapping(ptr.as_ptr(), old_layout.size());
+            }
+            // Safety: `ptr` is never used again is also an invariant which must
+            // be upheld by callers.
+            unsafe {
+                self.deallocate(ptr, old_layout);
+            }
         }
         Ok(new_ptr)
     }
@@ -114,12 +124,21 @@ unsafe impl const Allocator for ConstAllocator {
         old_layout: Layout,
         new_layout: Layout,
     ) -> Result<NonNull<[u8]>, AllocError> {
-        let new_ptr = self.grow(ptr, old_layout, new_layout)?;
+        // Safety: Invariants of `grow_zeroed` and `grow` are the same, and must
+        // be enforced by callers.
+        let new_ptr = unsafe { self.grow(ptr, old_layout, new_layout)? };
         if new_layout.size() > 0 {
             let old_size = old_layout.size();
             let new_size = new_layout.size();
             let raw_ptr = new_ptr.as_mut_ptr();
-            raw_ptr.add(old_size).write_bytes(0, new_size - old_size);
+            // Safety:
+            // - `grow` returned Ok, so the returned pointer must be valid for
+            //   `new_size` bytes
+            // - `new_size` must be larger than `old_size`, which is an
+            //   invariant which must be upheld by callers.
+            unsafe {
+                raw_ptr.add(old_size).write_bytes(0, new_size - old_size);
+            }
         }
         Ok(new_ptr)
     }
@@ -137,8 +156,18 @@ unsafe impl const Allocator for ConstAllocator {
 
         let new_ptr = self.allocate(new_layout)?;
         if new_layout.size() > 0 {
-            new_ptr.as_mut_ptr().copy_from_nonoverlapping(ptr.as_ptr(), new_layout.size());
-            self.deallocate(ptr, old_layout);
+            // Safety: `new_ptr` and `ptr` are valid for reads/writes of
+            // `new_layout.size()` because of the invariants of shrink, which
+            // include `new_layout.size()` being smaller than (or equal to)
+            // `old_layout.size()`.
+            unsafe {
+                new_ptr.as_mut_ptr().copy_from_nonoverlapping(ptr.as_ptr(), new_layout.size());
+            }
+            // Safety: `ptr` is never used again is also an invariant which must
+            // be upheld by callers.
+            unsafe {
+                self.deallocate(ptr, old_layout);
+            }
         }
         Ok(new_ptr)
     }
diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs
index d066ec03ee5..d6d2b055b23 100644
--- a/library/alloc/tests/lib.rs
+++ b/library/alloc/tests/lib.rs
@@ -48,6 +48,7 @@
 #![feature(once_cell)]
 #![feature(drain_keep_rest)]
 #![deny(fuzzy_provenance_casts)]
+#![deny(unsafe_op_in_unsafe_fn)]
 
 use std::collections::hash_map::DefaultHasher;
 use std::hash::{Hash, Hasher};
diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs
index e0271187044..7ebed0d5ca6 100644
--- a/library/alloc/tests/vec.rs
+++ b/library/alloc/tests/vec.rs
@@ -1089,7 +1089,8 @@ fn test_into_iter_drop_allocator() {
         }
 
         unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
-            System.deallocate(ptr, layout)
+            // Safety: Invariants passed to caller.
+            unsafe { System.deallocate(ptr, layout) }
         }
     }