diff options
| author | Oliver Scherer <github35764891676564198441@oli-obk.de> | 2018-11-03 13:03:05 +0100 |
|---|---|---|
| committer | Oliver Scherer <github35764891676564198441@oli-obk.de> | 2018-12-04 10:17:36 +0100 |
| commit | 02b22323f129446c9e2255d0eeab6c7ab17aac52 (patch) | |
| tree | 93ab14678f78998875c30fe591f048599b5ea5b5 /src/libcore | |
| parent | cc3470ce3b0ef74eab0f46d865d4d6021911b284 (diff) | |
| download | rust-02b22323f129446c9e2255d0eeab6c7ab17aac52.tar.gz rust-02b22323f129446c9e2255d0eeab6c7ab17aac52.zip | |
Make sure the initialization of constrained int range newtypes is unsafe
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/lib.rs | 1 | ||||
| -rw-r--r-- | src/libcore/nonzero.rs | 10 | ||||
| -rw-r--r-- | src/libcore/num/mod.rs | 4 | ||||
| -rw-r--r-- | src/libcore/ptr.rs | 14 |
4 files changed, 19 insertions, 10 deletions
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 726e891df0c..d070160609d 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -93,6 +93,7 @@ #![feature(never_type)] #![feature(nll)] #![feature(exhaustive_patterns)] +#![cfg_attr(not(stage0), feature(min_const_unsafe_fn))] #![feature(no_core)] #![feature(on_unimplemented)] #![feature(optin_builtin_traits)] diff --git a/src/libcore/nonzero.rs b/src/libcore/nonzero.rs index 436cd1fc057..22d93a5301e 100644 --- a/src/libcore/nonzero.rs +++ b/src/libcore/nonzero.rs @@ -15,10 +15,18 @@ use ops::{CoerceUnsized, DispatchFromDyn}; /// A wrapper type for raw pointers and integers that will never be /// NULL or 0 that might allow certain optimizations. #[rustc_layout_scalar_valid_range_start(1)] -#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] +#[derive(Copy, Eq, PartialEq, Ord, PartialOrd, Hash)] #[repr(transparent)] pub(crate) struct NonZero<T>(pub(crate) T); +// Do not call `T::clone` as theoretically it could turn the field into `0` +// invalidating `NonZero`'s invariant. +impl<T: Copy> Clone for NonZero<T> { + fn clone(&self) -> Self { + unsafe { NonZero(self.0) } + } +} + impl<T: CoerceUnsized<U>, U> CoerceUnsized<NonZero<U>> for NonZero<T> {} impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<NonZero<U>> for NonZero<T> {} diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 805be431328..7f5d596b220 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -70,7 +70,7 @@ assert_eq!(size_of::<Option<std::num::", stringify!($Ty), ">>(), size_of::<", st #[stable(feature = "nonzero", since = "1.28.0")] #[inline] pub const unsafe fn new_unchecked(n: $Int) -> Self { - $Ty(NonZero(n)) + $Ty(unsafe { NonZero(n) }) } /// Create a non-zero if the given value is not zero. @@ -78,7 +78,7 @@ assert_eq!(size_of::<Option<std::num::", stringify!($Ty), ">>(), size_of::<", st #[inline] pub fn new(n: $Int) -> Option<Self> { if n != 0 { - Some($Ty(NonZero(n))) + Some($Ty(unsafe { NonZero(n) })) } else { None } diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index d3a74ed2a68..a07c7260f71 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -2759,7 +2759,7 @@ impl<T: ?Sized> Unique<T> { /// Creates a new `Unique` if `ptr` is non-null. pub fn new(ptr: *mut T) -> Option<Self> { if !ptr.is_null() { - Some(Unique { pointer: NonZero(ptr as _), _marker: PhantomData }) + Some(Unique { pointer: unsafe { NonZero(ptr as _) }, _marker: PhantomData }) } else { None } @@ -2815,14 +2815,14 @@ impl<T: ?Sized> fmt::Pointer for Unique<T> { #[unstable(feature = "ptr_internals", issue = "0")] impl<'a, T: ?Sized> From<&'a mut T> for Unique<T> { fn from(reference: &'a mut T) -> Self { - Unique { pointer: NonZero(reference as _), _marker: PhantomData } + Unique { pointer: unsafe { NonZero(reference as _) }, _marker: PhantomData } } } #[unstable(feature = "ptr_internals", issue = "0")] impl<'a, T: ?Sized> From<&'a T> for Unique<T> { fn from(reference: &'a T) -> Self { - Unique { pointer: NonZero(reference as _), _marker: PhantomData } + Unique { pointer: unsafe { NonZero(reference as _) }, _marker: PhantomData } } } @@ -2895,7 +2895,7 @@ impl<T: ?Sized> NonNull<T> { #[stable(feature = "nonnull", since = "1.25.0")] #[inline] pub const unsafe fn new_unchecked(ptr: *mut T) -> Self { - NonNull { pointer: NonZero(ptr as _) } + NonNull { pointer: unsafe { NonZero(ptr as _) } } } /// Creates a new `NonNull` if `ptr` is non-null. @@ -2903,7 +2903,7 @@ impl<T: ?Sized> NonNull<T> { #[inline] pub fn new(ptr: *mut T) -> Option<Self> { if !ptr.is_null() { - Some(NonNull { pointer: NonZero(ptr as _) }) + Some(NonNull { pointer: unsafe { NonZero(ptr as _) } }) } else { None } @@ -3025,7 +3025,7 @@ impl<T: ?Sized> From<Unique<T>> for NonNull<T> { impl<'a, T: ?Sized> From<&'a mut T> for NonNull<T> { #[inline] fn from(reference: &'a mut T) -> Self { - NonNull { pointer: NonZero(reference as _) } + NonNull { pointer: unsafe { NonZero(reference as _) } } } } @@ -3033,6 +3033,6 @@ impl<'a, T: ?Sized> From<&'a mut T> for NonNull<T> { impl<'a, T: ?Sized> From<&'a T> for NonNull<T> { #[inline] fn from(reference: &'a T) -> Self { - NonNull { pointer: NonZero(reference as _) } + NonNull { pointer: unsafe { NonZero(reference as _) } } } } |
