Skip to content

Commit

Permalink
Make Layout::dangling return isize::MAX
Browse files Browse the repository at this point in the history
  • Loading branch information
chorman0773 committed Oct 12, 2024
1 parent 84684f7 commit b999cd0
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 20 deletions.
2 changes: 1 addition & 1 deletion lcrust/libraries/libcore/src/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ impl Layout {
pub fn dangling(&self) -> NonNull<u8> {
// SAFETY:
// _align is a power of two, and thus, the resulting pointer is non-null.
unsafe { NonNull::new_unchecked(self._align as *mut u8) }
unsafe { NonNull::new_unchecked(core::ptr::without_provenance(isize::MIN as usize)) }
}
}

Expand Down
31 changes: 25 additions & 6 deletions lcrust/libraries/libcore/src/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,29 +19,48 @@

#![unstable(feature = "core_intrinsics", issue = "none")]

#[stable]
pub use core::mem::transmute;

#[unstable(feature = "lccc_mir_macro", issue = "none")]
#[lcrust::builtin_macro]
pub macro mir($($tt:tt)*) {}

extern "rust-intrinsics" {
pub unsafe fn transmute<T, U>(x: T) -> U;

pub fn __builtin_size_of<T>() -> usize;
pub fn __builtin_align_of<T>() -> usize;
pub fn __builtin_known_align_of<T>() -> usize;

pub unsafe fn construct_in_place<T, F: FnOnce<Args> + FnPointer, Args: Tuple>(
dest: *mut T,
func: F,
args: Args,
);
pub fn __builtin_cmp<T: core::marker::Copy + core::cmp::PartialOrd, U>(a: T, b: T) -> U;

/// Compares two primitive values three way. `U` must be an integer type
pub const fn __builtin_cmp<
T: core::marker::Copy + core::cmp::PartialOrd,
U: core::marker::Copy,
>(
a: T,
b: T,
) -> U;

/// Same as [`Ord::max`][core::cmp::Ord::max] but only on primitives, and generally more efficient.
/// Also functions on `f32` and `f64`, see the corresponding function on those types for behaviour surrounding NaNs.
/// This may avoid a branch that may be present on the default function
pub fn __builtin_max_val<T: core::marker::Copy + core::cmp::PartialOrd>(a: T, b: T) -> T;
pub const fn __builtin_max_val<T: core::marker::Copy + core::cmp::PartialOrd>(a: T, b: T) -> T;
/// Same as [`Ord::min`][core::cmp::Ord::min] but only on primitives, and generally more efficient.
/// Also functions on `f32` and `f64`, see the corresponding function on those types for behaviour surrounding NaNs.
/// This may avoid a branch that may be present on the default function
pub fn __builtin_min_val<T: core::marker::Copy + core::cmp::PartialOrd>(a: T, b: T) -> T;
pub const fn __builtin_min_val<T: core::marker::Copy + core::cmp::PartialOrd>(a: T, b: T) -> T;
/// Same as [`Ord::clamp`][core::cmp::Ord::clamp] but only on primitives, and generally more efficient.
/// Also functions on `f32` and `f64`, see the corresponding function on those types for behaviour surrounding NaNs.
/// This may avoid a branch that may be present on the default function.
///
///
/// Note: This function may have unpredictable results, but does not have undefined behaviour, if `lower` > `upper`.
pub fn __builtin_clamp_val<T: core::marker::Copy + core::cmp::PartialOrd>(
pub const fn __builtin_clamp_val<T: core::marker::Copy + core::cmp::PartialOrd>(
val: T,
lower: T,
upper: T,
Expand Down
40 changes: 40 additions & 0 deletions lcrust/libraries/libcore/src/mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,3 +171,43 @@ pub const fn align_of<T>() -> usize {
pub const fn size_of_val<T: ?Sized>(x: &T) -> usize {
intrinsics::__builtin_size_of_val(x)
}

pub const fn align_of_val<T: ?Sized>(x: &T) -> usize {
intrinsics::__builtin_align_of_val(x)
}

pub const unsafe fn transmute_copy<T: ?Sized, U>(x: &T) -> U {
if const { core::intrinsics::__builtin_known_align_of::<T>() < core::mem::align_of::<U>() } {
(x as *const T).cast::<U>().read_unaligned()
} else {
(x as *const T).cast::<U>().read()
}
}

pub const unsafe fn transmute<T, U>(x: T) -> U {
const {
assert_eq!(
core::mem::size_of::<T>(),
core::mem::size_of::<U>(),
"Cannot transmute between differently sized types"
);
}

transmute_unchecked(x)
}

#[unstable(feature = "transmute_unchecked")]
#[inline(always)]
pub const unsafe fn transmute_unchecked<T, U>(x: T) -> U {
union Transmuter<T, U> {
val: ManuallyDrop<T>,
result: ManuallyDrop<U>,
}

ManuallyDrop::into_inner(
Transmuter {
val: ManuallyDrop::new(x),
}
.result,
)
}
15 changes: 2 additions & 13 deletions lcrust/libraries/libcore/src/ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,8 @@ pub fn slice_from_raw_parts_mut(ptr: *mut T, len: usize) -> *mut [T] {
}

#[repr(transparent)]
#[__lccc::transparent_as_unreified_field] // Fields with the type just become the transparent field type.
pub struct NonNull<T: ?Sized> {
#[__lccc::xlang_pointer_attributes(nonnull)]
#[lcrust::nonnull_pointer]
ptr: *const T,
}

Expand All @@ -103,16 +102,7 @@ impl<T: ?Sized> Copy for NonNull<T> {}

impl<T> NonNull<T> {
pub const fn dangling() -> Self {
// If std is built with debug-assertions=1 (--debug & -Z build-std), or the randomize-dangling feature
// Then mess with code that relies on the unspecified implementation of NonNull::<T>::dangling()
let ptr = if cfg!(debug_assertions) || cfg!(feature = "randomize-dangling") {
(::__lccc::__random_bytes!() & !(::__lccc::builtins::Rust::align_of::<T>() - 1))
as *const T
} else {
::__lccc::builtins::Rust::align_of::<T>() as *const T
};

NonNull { ptr }
core::alloc::Layout::of::<T>().dangling().cast()
}
}

Expand Down Expand Up @@ -162,7 +152,6 @@ impl<T: ?Sized> From<&mut T> for NonNull<T> {

#[repr(transparent)]
#[unstable(feature = "lccc_unique_ptr")]
#[__lccc::transparent_as_unreified_field]
pub struct Unique<T: ?Sized> {
#[__lccc::xlang_pointer_attributes(aligned)]
ptr: NonNull<T>,
Expand Down

0 comments on commit b999cd0

Please sign in to comment.