Skip to content

Commit

Permalink
rust-lang#66219 documented unsafe in core::{alloc, hash}
Browse files Browse the repository at this point in the history
  • Loading branch information
foeb committed Nov 10, 2019
1 parent 5797593 commit d78c056
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 13 deletions.
15 changes: 8 additions & 7 deletions src/libcore/alloc.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
//! Memory allocation APIs

// ignore-tidy-undocumented-unsafe

#![stable(feature = "alloc_module", since = "1.28.0")]

use crate::cmp;
Expand Down Expand Up @@ -88,6 +86,7 @@ impl Layout {
return Err(LayoutErr { private: () });
}

// SAFETY: performed checks above
unsafe {
Ok(Layout::from_size_align_unchecked(size, align))
}
Expand Down Expand Up @@ -120,11 +119,11 @@ impl Layout {
#[inline]
pub fn new<T>() -> Self {
let (size, align) = size_align::<T>();
// Note that the align is guaranteed by rustc to be a power of two and
debug_assert!(Layout::from_size_align(size, align).is_ok());
// SAFETY: Note that the align is guaranteed by rustc to be a power of two and
// the size+align combo is guaranteed to fit in our address space. As a
// result use the unchecked constructor here to avoid inserting code
// that panics if it isn't optimized well enough.
debug_assert!(Layout::from_size_align(size, align).is_ok());
unsafe {
Layout::from_size_align_unchecked(size, align)
}
Expand All @@ -137,8 +136,8 @@ impl Layout {
#[inline]
pub fn for_value<T: ?Sized>(t: &T) -> Self {
let (size, align) = (mem::size_of_val(t), mem::align_of_val(t));
// See rationale in `new` for why this us using an unsafe variant below
debug_assert!(Layout::from_size_align(size, align).is_ok());
// SAFETY: See rationale in `new` for why this us using an unsafe variant below
unsafe {
Layout::from_size_align_unchecked(size, align)
}
Expand Down Expand Up @@ -243,9 +242,9 @@ impl Layout {
let alloc_size = padded_size.checked_mul(n)
.ok_or(LayoutErr { private: () })?;

// SAFETY: self.align is already known to be valid and alloc_size has been
// padded already.
unsafe {
// self.align is already known to be valid and alloc_size has been
// padded already.
Ok((Layout::from_size_align_unchecked(alloc_size, self.align()), padded_size))
}
}
Expand Down Expand Up @@ -1074,6 +1073,7 @@ pub unsafe trait Alloc {
{
let k = Layout::new::<T>();
if k.size() > 0 {
// SAFETY: layout has nonzero size
unsafe { self.alloc(k).map(|p| p.cast()) }
} else {
Err(AllocErr)
Expand Down Expand Up @@ -1143,6 +1143,7 @@ pub unsafe trait Alloc {
{
match Layout::array::<T>(n) {
Ok(ref layout) if layout.size() > 0 => {
// SAFETY: layout has nonzero size
unsafe {
self.alloc(layout.clone()).map(|p| p.cast())
}
Expand Down
8 changes: 4 additions & 4 deletions src/libcore/hash/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,6 @@
//! }
//! ```

// ignore-tidy-undocumented-unsafe

#![stable(feature = "rust1", since = "1.0.0")]

use crate::fmt;
Expand Down Expand Up @@ -569,6 +567,8 @@ mod impls {
fn hash_slice<H: Hasher>(data: &[$ty], state: &mut H) {
let newlen = data.len() * mem::size_of::<$ty>();
let ptr = data.as_ptr() as *const u8;
// SAFETY: all of the requirements for from_raw_parts are guaranteed since
// data is a slice
state.write(unsafe { slice::from_raw_parts(ptr, newlen) })
}
}
Expand Down Expand Up @@ -688,7 +688,7 @@ mod impls {
// Thin pointer
state.write_usize(*self as *const () as usize);
} else {
// Fat pointer
// SAFETY: since it's not a thin pointer, it's a fat pointer
let (a, b) = unsafe {
*(self as *const Self as *const (usize, usize))
};
Expand All @@ -705,7 +705,7 @@ mod impls {
// Thin pointer
state.write_usize(*self as *const () as usize);
} else {
// Fat pointer
// SAFETY: since it's not a thin pointer, it's a fat pointer
let (a, b) = unsafe {
*(self as *const Self as *const (usize, usize))
};
Expand Down
9 changes: 7 additions & 2 deletions src/libcore/hash/sip.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
//! An implementation of SipHash.

// ignore-tidy-undocumented-unsafe

#![allow(deprecated)] // the types in this module are deprecated

use crate::marker::PhantomData;
Expand Down Expand Up @@ -222,8 +220,10 @@ impl<S: Sip> Hasher<S> {
let needed = 8 - self.ntail;
let fill = cmp::min(length, needed);
if fill == 8 {
// SAFETY: msg has exactly sizeof(u64) == 8
self.tail = unsafe { load_int_le!(msg, 0, u64) };
} else {
// SAFETY: fill < 7
self.tail |= unsafe { u8to64_le(msg, 0, fill) } << (8 * self.ntail);
if length < needed {
self.ntail += length;
Expand All @@ -236,6 +236,7 @@ impl<S: Sip> Hasher<S> {

// Buffered tail is now flushed, process new input.
self.ntail = length - needed;
// SAFETY: self.ntail + needed - 1 = length - 1 < 8
self.tail = unsafe { u8to64_le(msg, needed, self.ntail) };
}
}
Expand Down Expand Up @@ -270,6 +271,7 @@ impl<S: Sip> super::Hasher for Hasher<S> {
// see short_write comment for explanation
#[inline]
fn write_usize(&mut self, i: usize) {
// SAFETY: bytes leaves scope as i does
let bytes = unsafe {
crate::slice::from_raw_parts(&i as *const usize as *const u8, mem::size_of::<usize>())
};
Expand All @@ -291,6 +293,7 @@ impl<S: Sip> super::Hasher for Hasher<S> {

if self.ntail != 0 {
needed = 8 - self.ntail;
// SAFETY: needed < 8 since self.ntail != 0
self.tail |= unsafe { u8to64_le(msg, 0, cmp::min(length, needed)) } << 8 * self.ntail;
if length < needed {
self.ntail += length;
Expand All @@ -309,6 +312,7 @@ impl<S: Sip> super::Hasher for Hasher<S> {

let mut i = needed;
while i < len - left {
// SAFETY: i + 8 <= length
let mi = unsafe { load_int_le!(msg, i, u64) };

self.state.v3 ^= mi;
Expand All @@ -318,6 +322,7 @@ impl<S: Sip> super::Hasher for Hasher<S> {
i += 8;
}

// SAFETY: left < 8
self.tail = unsafe { u8to64_le(msg, i, left) };
self.ntail = left;
}
Expand Down

0 comments on commit d78c056

Please sign in to comment.