Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -713,7 +713,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
let res = CValue::by_val(swap(&mut fx.bcx, val), arg.layout());
ret.write_cvalue(fx, res);
}
sym::assert_inhabited | sym::assert_zero_valid | sym::assert_uninit_valid => {
sym::assert_inhabited | sym::assert_zero_valid | sym::assert_mem_uninitialized_valid => {
intrinsic_args!(fx, args => (); intrinsic);

let layout = fx.layout_of(substs.type_at(0));
Expand Down Expand Up @@ -742,7 +742,9 @@ fn codegen_regular_intrinsic_call<'tcx>(
return;
}

if intrinsic == sym::assert_uninit_valid && !fx.tcx.permits_uninit_init(layout) {
if intrinsic == sym::assert_mem_uninitialized_valid
&& !fx.tcx.permits_uninit_init(layout)
{
with_no_trimmed_paths!({
crate::base::codegen_panic(
fx,
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_codegen_ssa/src/mir/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -666,12 +666,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
enum AssertIntrinsic {
Inhabited,
ZeroValid,
UninitValid,
MemUninitializedValid,
}
let panic_intrinsic = intrinsic.and_then(|i| match i {
sym::assert_inhabited => Some(AssertIntrinsic::Inhabited),
sym::assert_zero_valid => Some(AssertIntrinsic::ZeroValid),
sym::assert_uninit_valid => Some(AssertIntrinsic::UninitValid),
sym::assert_mem_uninitialized_valid => Some(AssertIntrinsic::MemUninitializedValid),
_ => None,
});
if let Some(intrinsic) = panic_intrinsic {
Expand All @@ -682,7 +682,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let do_panic = match intrinsic {
Inhabited => layout.abi.is_uninhabited(),
ZeroValid => !bx.tcx().permits_zero_init(layout),
UninitValid => !bx.tcx().permits_uninit_init(layout),
MemUninitializedValid => !bx.tcx().permits_uninit_init(layout),
};
Some(if do_panic {
let msg_str = with_no_visible_paths!({
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_const_eval/src/interpret/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
sym::transmute => {
self.copy_op(&args[0], dest, /*allow_transmute*/ true)?;
}
sym::assert_inhabited | sym::assert_zero_valid | sym::assert_uninit_valid => {
sym::assert_inhabited
| sym::assert_zero_valid
| sym::assert_mem_uninitialized_valid => {
let ty = instance.substs.type_at(0);
let layout = self.layout_of(ty)?;

Expand Down Expand Up @@ -464,7 +466,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}
}

if intrinsic_name == sym::assert_uninit_valid {
if intrinsic_name == sym::assert_mem_uninitialized_valid {
let should_panic = !self.tcx.permits_uninit_init(layout);

if should_panic {
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_hir_analysis/src/check/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: DefId) -> hir
sym::abort
| sym::assert_inhabited
| sym::assert_zero_valid
| sym::assert_uninit_valid
| sym::assert_mem_uninitialized_valid
| sym::size_of
| sym::min_align_of
| sym::needs_drop
Expand Down Expand Up @@ -193,9 +193,9 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
}
sym::rustc_peek => (1, vec![param(0)], param(0)),
sym::caller_location => (0, vec![], tcx.caller_location_ty()),
sym::assert_inhabited | sym::assert_zero_valid | sym::assert_uninit_valid => {
(1, Vec::new(), tcx.mk_unit())
}
sym::assert_inhabited
| sym::assert_zero_valid
| sym::assert_mem_uninitialized_valid => (1, Vec::new(), tcx.mk_unit()),
sym::forget => (1, vec![param(0)], tcx.mk_unit()),
sym::transmute => (2, vec![param(0)], param(1)),
sym::prefetch_read_data
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -377,9 +377,9 @@ symbols! {
assert_eq_macro,
assert_inhabited,
assert_macro,
assert_mem_uninitialized_valid,
assert_ne_macro,
assert_receiver_is_total_eq,
assert_uninit_valid,
assert_zero_valid,
asserting,
associated_const_equality,
Expand Down
7 changes: 4 additions & 3 deletions library/core/src/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -959,13 +959,14 @@ extern "rust-intrinsic" {
#[rustc_safe_intrinsic]
pub fn assert_zero_valid<T>();

/// A guard for unsafe functions that cannot ever be executed if `T` has invalid
/// bit patterns: This will statically either panic, or do nothing.
/// A guard for `std::mem::uninitialized`. Checks whether a repeated bit pattern `0x01`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checks whether a repeated bit pattern 0x01 is legal for T

Except if we decide to change the bit pattern (unlikely) or -Zstrict-init-checks is passed. Yes it's redundant, but it might be better to just say "Checks whether mem::uninitialized should panic for T" 🤷

/// is legal for `T`: This will statically either panic, or do nothing.
///
/// This intrinsic does not have a stable counterpart.
#[rustc_const_unstable(feature = "const_assert_type2", issue = "none")]
#[rustc_safe_intrinsic]
pub fn assert_uninit_valid<T>();
#[cfg(not(bootstrap))]
pub fn assert_mem_uninitialized_valid<T>();

/// Gets a reference to a static `Location` indicating where it was called.
///
Expand Down
3 changes: 2 additions & 1 deletion library/core/src/mem/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -682,7 +682,8 @@ pub unsafe fn zeroed<T>() -> T {
pub unsafe fn uninitialized<T>() -> T {
// SAFETY: the caller must guarantee that an uninitialized value is valid for `T`.
unsafe {
intrinsics::assert_uninit_valid::<T>();
#[cfg(not(bootstrap))] // If the compiler hits this itself then it deserves the UB.
intrinsics::assert_mem_uninitialized_valid::<T>();
let mut val = MaybeUninit::<T>::uninit();

// Fill memory with 0x01, as an imperfect mitigation for old code that uses this function on
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/consts/assert-type-intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ fn main() {
//~^ERROR: evaluation of constant value failed
};
const _BAD2: () = {
intrinsics::assert_uninit_valid::<&'static i32>();
intrinsics::assert_mem_uninitialized_valid::<&'static i32>();
//~^ERROR: evaluation of constant value failed
};
const _BAD3: () = {
Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/consts/assert-type-intrinsics.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ LL | MaybeUninit::<!>::uninit().assume_init();
error[E0080]: evaluation of constant value failed
--> $DIR/assert-type-intrinsics.rs:16:9
|
LL | intrinsics::assert_uninit_valid::<&'static i32>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to leave type `&i32` uninitialized, which is invalid
LL | intrinsics::assert_mem_uninitialized_valid::<&'static i32>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to leave type `&i32` uninitialized, which is invalid

error[E0080]: evaluation of constant value failed
--> $DIR/assert-type-intrinsics.rs:20:9
Expand Down