Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 3 pull requests #127705

Merged
merged 14 commits into from
Jul 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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: 6 additions & 0 deletions library/alloc/src/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1213,6 +1213,9 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
/// let static_ref: &'static mut usize = Box::leak(x);
/// *static_ref += 1;
/// assert_eq!(*static_ref, 42);
/// # // FIXME(https://github.com/rust-lang/miri/issues/3670):
/// # // use -Zmiri-disable-leak-check instead of unleaking in tests meant to leak.
/// # drop(unsafe { Box::from_raw(static_ref) });
/// ```
///
/// Unsized data:
Expand All @@ -1222,6 +1225,9 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
/// let static_ref = Box::leak(x);
/// static_ref[0] = 4;
/// assert_eq!(*static_ref, [4, 2, 3]);
/// # // FIXME(https://github.com/rust-lang/miri/issues/3670):
/// # // use -Zmiri-disable-leak-check instead of unleaking in tests meant to leak.
/// # drop(unsafe { Box::from_raw(static_ref) });
/// ```
#[stable(feature = "box_leak", since = "1.26.0")]
#[inline]
Expand Down
6 changes: 6 additions & 0 deletions library/alloc/src/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1277,6 +1277,8 @@ impl<T: ?Sized> Rc<T> {
///
/// let five = Rc::from_raw(ptr);
/// assert_eq!(2, Rc::strong_count(&five));
/// # // Prevent leaks for Miri.
/// # Rc::decrement_strong_count(ptr);
/// }
/// ```
#[inline]
Expand Down Expand Up @@ -1345,6 +1347,8 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> {
/// let x = Rc::new("hello".to_owned());
/// let x_ptr = Rc::into_raw(x);
/// assert_eq!(unsafe { &*x_ptr }, "hello");
/// # // Prevent leaks for Miri.
/// # drop(unsafe { Rc::from_raw(x_ptr) });
/// ```
#[must_use = "losing the pointer will leak memory"]
#[stable(feature = "rc_raw", since = "1.17.0")]
Expand Down Expand Up @@ -1572,6 +1576,8 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> {
///
/// let five = Rc::from_raw_in(ptr, System);
/// assert_eq!(2, Rc::strong_count(&five));
/// # // Prevent leaks for Miri.
/// # Rc::decrement_strong_count_in(ptr, System);
/// }
/// ```
#[inline]
Expand Down
3 changes: 3 additions & 0 deletions library/alloc/src/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1984,6 +1984,9 @@ impl String {
/// let x = String::from("bucket");
/// let static_ref: &'static mut str = x.leak();
/// assert_eq!(static_ref, "bucket");
/// # // FIXME(https://github.com/rust-lang/miri/issues/3670):
/// # // use -Zmiri-disable-leak-check instead of unleaking in tests meant to leak.
/// # drop(unsafe { Box::from_raw(static_ref) });
/// ```
#[stable(feature = "string_leak", since = "1.72.0")]
#[inline]
Expand Down
6 changes: 6 additions & 0 deletions library/alloc/src/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1414,6 +1414,8 @@ impl<T: ?Sized> Arc<T> {
/// // the `Arc` between threads.
/// let five = Arc::from_raw(ptr);
/// assert_eq!(2, Arc::strong_count(&five));
/// # // Prevent leaks for Miri.
/// # Arc::decrement_strong_count(ptr);
/// }
/// ```
#[inline]
Expand Down Expand Up @@ -1484,6 +1486,8 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> {
/// let x = Arc::new("hello".to_owned());
/// let x_ptr = Arc::into_raw(x);
/// assert_eq!(unsafe { &*x_ptr }, "hello");
/// # // Prevent leaks for Miri.
/// # drop(unsafe { Arc::from_raw(x_ptr) });
/// ```
#[must_use = "losing the pointer will leak memory"]
#[stable(feature = "rc_raw", since = "1.17.0")]
Expand Down Expand Up @@ -1766,6 +1770,8 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> {
/// // the `Arc` between threads.
/// let five = Arc::from_raw_in(ptr, System);
/// assert_eq!(2, Arc::strong_count(&five));
/// # // Prevent leaks for Miri.
/// # Arc::decrement_strong_count_in(ptr, System);
/// }
/// ```
#[inline]
Expand Down
7 changes: 6 additions & 1 deletion library/alloc/src/vec/into_iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,15 @@ impl<T, A: Allocator> IntoIter<T, A> {
/// This is roughly equivalent to the following, but more efficient
///
/// ```
/// # let mut into_iter = Vec::<u8>::with_capacity(10).into_iter();
/// # let mut vec = Vec::<u8>::with_capacity(10);
/// # let ptr = vec.as_mut_ptr();
/// # let mut into_iter = vec.into_iter();
/// let mut into_iter = std::mem::replace(&mut into_iter, Vec::new().into_iter());
/// (&mut into_iter).for_each(drop);
/// std::mem::forget(into_iter);
/// # // FIXME(https://github.com/rust-lang/miri/issues/3670):
/// # // use -Zmiri-disable-leak-check instead of unleaking in tests meant to leak.
/// # drop(unsafe { Vec::<u8>::from_raw_parts(ptr, 0, 10) });
/// ```
///
/// This method is used by in-place iteration, refer to the vec::in_place_collect
Expand Down
6 changes: 6 additions & 0 deletions library/alloc/src/vec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1473,6 +1473,9 @@ impl<T, A: Allocator> Vec<T, A> {
/// // 2. `0 <= capacity` always holds whatever `capacity` is.
/// unsafe {
/// vec.set_len(0);
/// # // FIXME(https://github.com/rust-lang/miri/issues/3670):
/// # // use -Zmiri-disable-leak-check instead of unleaking in tests meant to leak.
/// # vec.set_len(3);
/// }
/// ```
///
Expand Down Expand Up @@ -2391,6 +2394,9 @@ impl<T, A: Allocator> Vec<T, A> {
/// let static_ref: &'static mut [usize] = x.leak();
/// static_ref[0] += 1;
/// assert_eq!(static_ref, &[2, 2, 3]);
/// # // FIXME(https://github.com/rust-lang/miri/issues/3670):
/// # // use -Zmiri-disable-leak-check instead of unleaking in tests meant to leak.
/// # drop(unsafe { Box::from_raw(static_ref) });
/// ```
#[stable(feature = "vec_leak", since = "1.47.0")]
#[inline]
Expand Down
3 changes: 3 additions & 0 deletions library/core/src/mem/manually_drop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ impl<T> ManuallyDrop<T> {
/// x.truncate(5); // You can still safely operate on the value
/// assert_eq!(*x, "Hello");
/// // But `Drop` will not be run here
/// # // FIXME(https://github.com/rust-lang/miri/issues/3670):
/// # // use -Zmiri-disable-leak-check instead of unleaking in tests meant to leak.
/// # let _ = ManuallyDrop::into_inner(x);
/// ```
#[must_use = "if you don't need the wrapper, you can use `mem::forget` instead"]
#[stable(feature = "manually_drop", since = "1.20.0")]
Expand Down
15 changes: 15 additions & 0 deletions library/core/src/mem/maybe_uninit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,8 @@ impl<T> MaybeUninit<T> {
/// use std::mem::MaybeUninit;
///
/// let v: MaybeUninit<Vec<u8>> = MaybeUninit::new(vec![42]);
/// # // Prevent leaks for Miri
/// # unsafe { let _ = MaybeUninit::assume_init(v); }
/// ```
///
/// [`assume_init`]: MaybeUninit::assume_init
Expand Down Expand Up @@ -446,6 +448,9 @@ impl<T> MaybeUninit<T> {
/// let mut x = MaybeUninit::<String>::uninit();
///
/// x.write("Hello".to_string());
/// # // FIXME(https://github.com/rust-lang/miri/issues/3670):
/// # // use -Zmiri-disable-leak-check instead of unleaking in tests meant to leak.
/// # unsafe { MaybeUninit::assume_init_drop(&mut x); }
/// // This leaks the contained string:
/// x.write("hello".to_string());
/// // x is initialized now:
Expand Down Expand Up @@ -506,6 +511,8 @@ impl<T> MaybeUninit<T> {
/// // Create a reference into the `MaybeUninit<T>`. This is okay because we initialized it.
/// let x_vec = unsafe { &*x.as_ptr() };
/// assert_eq!(x_vec.len(), 3);
/// # // Prevent leaks for Miri
/// # unsafe { MaybeUninit::assume_init_drop(&mut x); }
/// ```
///
/// *Incorrect* usage of this method:
Expand Down Expand Up @@ -545,6 +552,8 @@ impl<T> MaybeUninit<T> {
/// let x_vec = unsafe { &mut *x.as_mut_ptr() };
/// x_vec.push(3);
/// assert_eq!(x_vec.len(), 4);
/// # // Prevent leaks for Miri
/// # unsafe { MaybeUninit::assume_init_drop(&mut x); }
/// ```
///
/// *Incorrect* usage of this method:
Expand Down Expand Up @@ -746,6 +755,8 @@ impl<T> MaybeUninit<T> {
/// use std::mem::MaybeUninit;
///
/// let mut x = MaybeUninit::<Vec<u32>>::uninit();
/// # let mut x_mu = x;
/// # let mut x = &mut x_mu;
/// // Initialize `x`:
/// x.write(vec![1, 2, 3]);
/// // Now that our `MaybeUninit<_>` is known to be initialized, it is okay to
Expand All @@ -755,6 +766,8 @@ impl<T> MaybeUninit<T> {
/// x.assume_init_ref()
/// };
/// assert_eq!(x, &vec![1, 2, 3]);
/// # // Prevent leaks for Miri
/// # unsafe { MaybeUninit::assume_init_drop(&mut x_mu); }
/// ```
///
/// ### *Incorrect* usages of this method:
Expand Down Expand Up @@ -1088,6 +1101,8 @@ impl<T> MaybeUninit<T> {
/// let init = MaybeUninit::clone_from_slice(&mut dst, &src);
///
/// assert_eq!(init, src);
/// # // Prevent leaks for Miri
/// # unsafe { std::ptr::drop_in_place(init); }
/// ```
///
/// ```
Expand Down
2 changes: 2 additions & 0 deletions library/core/src/ptr/non_null.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1663,6 +1663,8 @@ impl<T> NonNull<[T]> {
/// // Note that calling `memory.as_mut()` is not allowed here as the content may be uninitialized.
/// # #[allow(unused_variables)]
/// let slice: &mut [MaybeUninit<u8>] = unsafe { memory.as_uninit_slice_mut() };
/// # // Prevent leaks for Miri.
/// # unsafe { Global.deallocate(memory.cast(), Layout::new::<[u8; 32]>()); }
/// # Ok::<_, std::alloc::AllocError>(())
/// ```
#[inline]
Expand Down
4 changes: 4 additions & 0 deletions library/std/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ std_detect_file_io = ["std_detect/std_detect_file_io"]
std_detect_dlsym_getauxval = ["std_detect/std_detect_dlsym_getauxval"]
std_detect_env_override = ["std_detect/std_detect_env_override"]

# Enable using raw-dylib for Windows imports.
# This will eventually be the default.
windows_raw_dylib = []

[package.metadata.fortanix-sgx]
# Maximum possible number of threads when testing
threads = 125
Expand Down
3 changes: 3 additions & 0 deletions library/std/src/sync/condvar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ impl WaitTimeoutResult {
/// let pair = Arc::new((Mutex::new(false), Condvar::new()));
/// let pair2 = Arc::clone(&pair);
///
/// # let handle =
/// thread::spawn(move || {
/// let (lock, cvar) = &*pair2;
///
Expand All @@ -58,6 +59,8 @@ impl WaitTimeoutResult {
/// break
/// }
/// }
/// # // Prevent leaks for Miri.
/// # let _ = handle.join();
/// ```
#[must_use]
#[stable(feature = "wait_timeout", since = "1.5.0")]
Expand Down
129 changes: 63 additions & 66 deletions library/std/src/sys/pal/windows/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::alloc::{GlobalAlloc, Layout, System};
use crate::ffi::c_void;
use crate::ptr;
use crate::sync::atomic::{AtomicPtr, Ordering};
use crate::sys::c;
use crate::sys::c::{self, windows_targets};
use crate::sys::common::alloc::{realloc_fallback, MIN_ALIGN};
use core::mem::MaybeUninit;

Expand All @@ -17,74 +17,71 @@ mod tests;
// Flag to indicate that the memory returned by `HeapAlloc` should be zeroed.
const HEAP_ZERO_MEMORY: c::DWORD = 0x00000008;

#[link(name = "kernel32")]
extern "system" {
// Get a handle to the default heap of the current process, or null if the operation fails.
//
// SAFETY: Successful calls to this function within the same process are assumed to
// always return the same handle, which remains valid for the entire lifetime of the process.
//
// See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-getprocessheap
fn GetProcessHeap() -> c::HANDLE;
// Get a handle to the default heap of the current process, or null if the operation fails.
//
// SAFETY: Successful calls to this function within the same process are assumed to
// always return the same handle, which remains valid for the entire lifetime of the process.
//
// See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-getprocessheap
windows_targets::link!("kernel32.dll" "system" fn GetProcessHeap() -> c::HANDLE);

// Allocate a block of `dwBytes` bytes of memory from a given heap `hHeap`.
// The allocated memory may be uninitialized, or zeroed if `dwFlags` is
// set to `HEAP_ZERO_MEMORY`.
//
// Returns a pointer to the newly-allocated memory or null if the operation fails.
// The returned pointer will be aligned to at least `MIN_ALIGN`.
//
// SAFETY:
// - `hHeap` must be a non-null handle returned by `GetProcessHeap`.
// - `dwFlags` must be set to either zero or `HEAP_ZERO_MEMORY`.
//
// Note that `dwBytes` is allowed to be zero, contrary to some other allocators.
//
// See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-heapalloc
fn HeapAlloc(hHeap: c::HANDLE, dwFlags: c::DWORD, dwBytes: c::SIZE_T) -> c::LPVOID;
// Allocate a block of `dwBytes` bytes of memory from a given heap `hHeap`.
// The allocated memory may be uninitialized, or zeroed if `dwFlags` is
// set to `HEAP_ZERO_MEMORY`.
//
// Returns a pointer to the newly-allocated memory or null if the operation fails.
// The returned pointer will be aligned to at least `MIN_ALIGN`.
//
// SAFETY:
// - `hHeap` must be a non-null handle returned by `GetProcessHeap`.
// - `dwFlags` must be set to either zero or `HEAP_ZERO_MEMORY`.
//
// Note that `dwBytes` is allowed to be zero, contrary to some other allocators.
//
// See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-heapalloc
windows_targets::link!("kernel32.dll" "system" fn HeapAlloc(hheap: c::HANDLE, dwflags: u32, dwbytes: usize) -> *mut core::ffi::c_void);

// Reallocate a block of memory behind a given pointer `lpMem` from a given heap `hHeap`,
// to a block of at least `dwBytes` bytes, either shrinking the block in place,
// or allocating at a new location, copying memory, and freeing the original location.
//
// Returns a pointer to the reallocated memory or null if the operation fails.
// The returned pointer will be aligned to at least `MIN_ALIGN`.
// If the operation fails the given block will never have been freed.
//
// SAFETY:
// - `hHeap` must be a non-null handle returned by `GetProcessHeap`.
// - `dwFlags` must be set to zero.
// - `lpMem` must be a non-null pointer to an allocated block returned by `HeapAlloc` or
// `HeapReAlloc`, that has not already been freed.
// If the block was successfully reallocated at a new location, pointers pointing to
// the freed memory, such as `lpMem`, must not be dereferenced ever again.
//
// Note that `dwBytes` is allowed to be zero, contrary to some other allocators.
//
// See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-heaprealloc
fn HeapReAlloc(
hHeap: c::HANDLE,
dwFlags: c::DWORD,
lpMem: c::LPVOID,
dwBytes: c::SIZE_T,
) -> c::LPVOID;
// Reallocate a block of memory behind a given pointer `lpMem` from a given heap `hHeap`,
// to a block of at least `dwBytes` bytes, either shrinking the block in place,
// or allocating at a new location, copying memory, and freeing the original location.
//
// Returns a pointer to the reallocated memory or null if the operation fails.
// The returned pointer will be aligned to at least `MIN_ALIGN`.
// If the operation fails the given block will never have been freed.
//
// SAFETY:
// - `hHeap` must be a non-null handle returned by `GetProcessHeap`.
// - `dwFlags` must be set to zero.
// - `lpMem` must be a non-null pointer to an allocated block returned by `HeapAlloc` or
// `HeapReAlloc`, that has not already been freed.
// If the block was successfully reallocated at a new location, pointers pointing to
// the freed memory, such as `lpMem`, must not be dereferenced ever again.
//
// Note that `dwBytes` is allowed to be zero, contrary to some other allocators.
//
// See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-heaprealloc
windows_targets::link!("kernel32.dll" "system" fn HeapReAlloc(
hheap: c::HANDLE,
dwflags : u32,
lpmem: *const core::ffi::c_void,
dwbytes: usize
) -> *mut core::ffi::c_void);

// Free a block of memory behind a given pointer `lpMem` from a given heap `hHeap`.
// Returns a nonzero value if the operation is successful, and zero if the operation fails.
//
// SAFETY:
// - `hHeap` must be a non-null handle returned by `GetProcessHeap`.
// - `dwFlags` must be set to zero.
// - `lpMem` must be a pointer to an allocated block returned by `HeapAlloc` or `HeapReAlloc`,
// that has not already been freed.
// If the block was successfully freed, pointers pointing to the freed memory, such as `lpMem`,
// must not be dereferenced ever again.
//
// Note that `lpMem` is allowed to be null, which will not cause the operation to fail.
//
// See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-heapfree
fn HeapFree(hHeap: c::HANDLE, dwFlags: c::DWORD, lpMem: c::LPVOID) -> c::BOOL;
}
// Free a block of memory behind a given pointer `lpMem` from a given heap `hHeap`.
// Returns a nonzero value if the operation is successful, and zero if the operation fails.
//
// SAFETY:
// - `hHeap` must be a non-null handle returned by `GetProcessHeap`.
// - `dwFlags` must be set to zero.
// - `lpMem` must be a pointer to an allocated block returned by `HeapAlloc` or `HeapReAlloc`,
// that has not already been freed.
// If the block was successfully freed, pointers pointing to the freed memory, such as `lpMem`,
// must not be dereferenced ever again.
//
// Note that `lpMem` is allowed to be null, which will not cause the operation to fail.
//
// See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-heapfree
windows_targets::link!("kernel32.dll" "system" fn HeapFree(hheap: c::HANDLE, dwflags: u32, lpmem: *const core::ffi::c_void) -> c::BOOL);

// Cached handle to the default heap of the current process.
// Either a non-null handle returned by `GetProcessHeap`, or null when not yet initialized or `GetProcessHeap` failed.
Expand Down
2 changes: 1 addition & 1 deletion library/std/src/sys/pal/windows/c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::os::raw::{c_char, c_long, c_longlong, c_uint, c_ulong, c_ushort, c_vo
use crate::os::windows::io::{AsRawHandle, BorrowedHandle};
use crate::ptr;

mod windows_targets;
pub(super) mod windows_targets;

mod windows_sys;
pub use windows_sys::*;
Expand Down
Loading
Loading