diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 30f2f0ee05c..24742bb49b9 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -164,6 +164,7 @@ #![feature(allow_internal_unstable)] #![feature(associated_type_bounds)] #![feature(auto_traits)] +#![feature(cfg_sanitize)] #![feature(cfg_target_has_atomic)] #![feature(cfg_target_has_atomic_equal_alignment)] #![feature(const_fn_floating_point_arithmetic)] diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 234fa213da8..6351e6fbd13 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -654,6 +654,8 @@ pub unsafe fn zeroed() -> T { /// produce a value of type `T`, while doing nothing at all. /// /// **This function is deprecated.** Use [`MaybeUninit`] instead. +/// It also might be slower than using `MaybeUninit` due to mitigations that were put in place to +/// limit the potential harm caused by incorrect use of this function in legacy code. /// /// The reason for deprecation is that the function basically cannot be used /// correctly: it has the same effect as [`MaybeUninit::uninit().assume_init()`][uninit]. @@ -683,7 +685,15 @@ pub unsafe fn uninitialized() -> T { // SAFETY: the caller must guarantee that an uninitialized value is valid for `T`. unsafe { intrinsics::assert_uninit_valid::(); - MaybeUninit::uninit().assume_init() + let mut val = MaybeUninit::::uninit(); + + // Fill memory with 0x01, as an imperfect mitigation for old code that uses this function on + // bool, nonnull, and noundef types. But don't do this if we actively want to detect UB. + if !cfg!(any(miri, sanitize = "memory")) { + val.as_mut_ptr().write_bytes(0x01, 1); + } + + val.assume_init() } }