[PATCH] Avoid forming references to an uninitialized memory in DroplessArena
authorTomasz Miąsko <tomasz.miasko@gmail.com>
Sun, 14 Jun 2020 00:00:00 +0000 (00:00 +0000)
committerXimin Luo <infinity0@debian.org>
Thu, 6 Aug 2020 20:11:39 +0000 (21:11 +0100)
Return a pointer from `alloc_raw` instead of a slice. There is no
practical use for slice as a return type and changing it to a pointer
avoids forming references to an uninitialized memory.

Gbp-Pq: Name u-1f0895162ba5a783d4d73d5c263552eaca9343b3.patch

src/libarena/lib.rs
src/librustc_middle/ty/list.rs

index b06f55a14dadc5b334b045035f636604ffafd769..e3d974b25e5277108cc1c5baafce4a8b8bc55235 100644 (file)
@@ -375,7 +375,7 @@ impl DroplessArena {
     /// current memory chunk. Returns `None` if there is no free space left to
     /// satisfy the request.
     #[inline]
-    fn alloc_raw_without_grow(&self, bytes: usize, align: usize) -> Option<&mut [u8]> {
+    fn alloc_raw_without_grow(&self, bytes: usize, align: usize) -> Option<*mut u8> {
         let ptr = self.ptr.get() as usize;
         let end = self.end.get() as usize;
         // The allocation request fits into the current chunk iff:
@@ -391,14 +391,14 @@ impl DroplessArena {
         let new_ptr = aligned.checked_add(bytes)?;
         if new_ptr <= end {
             self.ptr.set(new_ptr as *mut u8);
-            unsafe { Some(slice::from_raw_parts_mut(aligned as *mut u8, bytes)) }
+            Some(aligned as *mut u8)
         } else {
             None
         }
     }
 
     #[inline]
-    pub fn alloc_raw(&self, bytes: usize, align: usize) -> &mut [u8] {
+    pub fn alloc_raw(&self, bytes: usize, align: usize) -> *mut u8 {
         assert!(bytes != 0);
         loop {
             if let Some(a) = self.alloc_raw_without_grow(bytes, align) {
@@ -414,7 +414,7 @@ impl DroplessArena {
     pub fn alloc<T>(&self, object: T) -> &mut T {
         assert!(!mem::needs_drop::<T>());
 
-        let mem = self.alloc_raw(mem::size_of::<T>(), mem::align_of::<T>()) as *mut _ as *mut T;
+        let mem = self.alloc_raw(mem::size_of::<T>(), mem::align_of::<T>()) as *mut T;
 
         unsafe {
             // Write into uninitialized memory.
@@ -439,13 +439,11 @@ impl DroplessArena {
         assert!(mem::size_of::<T>() != 0);
         assert!(!slice.is_empty());
 
-        let mem = self.alloc_raw(slice.len() * mem::size_of::<T>(), mem::align_of::<T>()) as *mut _
-            as *mut T;
+        let mem = self.alloc_raw(slice.len() * mem::size_of::<T>(), mem::align_of::<T>()) as *mut T;
 
         unsafe {
-            let arena_slice = slice::from_raw_parts_mut(mem, slice.len());
-            arena_slice.copy_from_slice(slice);
-            arena_slice
+            mem.copy_from_nonoverlapping(slice.as_ptr(), slice.len());
+            slice::from_raw_parts_mut(mem, slice.len())
         }
     }
 
@@ -488,7 +486,7 @@ impl DroplessArena {
                     return &mut [];
                 }
                 let size = len.checked_mul(mem::size_of::<T>()).unwrap();
-                let mem = self.alloc_raw(size, mem::align_of::<T>()) as *mut _ as *mut T;
+                let mem = self.alloc_raw(size, mem::align_of::<T>()) as *mut T;
                 unsafe { self.write_from_iter(iter, len, mem) }
             }
             (_, _) => {
@@ -503,7 +501,7 @@ impl DroplessArena {
                         let len = vec.len();
                         let start_ptr = self
                             .alloc_raw(len * mem::size_of::<T>(), mem::align_of::<T>())
-                            as *mut _ as *mut T;
+                            as *mut T;
                         vec.as_ptr().copy_to_nonoverlapping(start_ptr, len);
                         vec.set_len(0);
                         slice::from_raw_parts_mut(start_ptr, len)
@@ -547,8 +545,7 @@ pub struct DropArena {
 impl DropArena {
     #[inline]
     pub unsafe fn alloc<T>(&self, object: T) -> &mut T {
-        let mem =
-            self.arena.alloc_raw(mem::size_of::<T>(), mem::align_of::<T>()) as *mut _ as *mut T;
+        let mem = self.arena.alloc_raw(mem::size_of::<T>(), mem::align_of::<T>()) as *mut T;
         // Write into uninitialized memory.
         ptr::write(mem, object);
         let result = &mut *mem;
@@ -571,7 +568,7 @@ impl DropArena {
         let start_ptr = self
             .arena
             .alloc_raw(len.checked_mul(mem::size_of::<T>()).unwrap(), mem::align_of::<T>())
-            as *mut _ as *mut T;
+            as *mut T;
 
         let mut destructors = self.destructors.borrow_mut();
         // Reserve space for the destructors so we can't panic while adding them
index 161783bb370d44904b4a492ae05d2c55e1636f22..76c72e4c2603d53f7d8673b4fe9e73c548351ed9 100644 (file)
@@ -55,7 +55,7 @@ impl<T: Copy> List<T> {
             .dropless
             .alloc_raw(size, cmp::max(mem::align_of::<T>(), mem::align_of::<usize>()));
         unsafe {
-            let result = &mut *(mem.as_mut_ptr() as *mut List<T>);
+            let result = &mut *(mem as *mut List<T>);
             // Write the length
             result.len = slice.len();