-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Apply #![deny(unsafe_op_in_unsafe_fn)]
to sys/windows
#76676
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
Changes from all commits
c1665e7
fe6652f
b38c164
2106351
475df91
c5304ff
a6bb6d7
7c4738e
ef8baea
ff27e01
9057f5e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,61 +1,96 @@ | ||
#![deny(unsafe_op_in_unsafe_fn)] | ||
|
||
use crate::alloc::{GlobalAlloc, Layout, System}; | ||
use crate::ptr; | ||
use crate::sys::c; | ||
use crate::sys_common::alloc::{realloc_fallback, MIN_ALIGN}; | ||
|
||
#[repr(C)] | ||
struct Header(*mut u8); | ||
|
||
unsafe fn get_header<'a>(ptr: *mut u8) -> &'a mut Header { | ||
&mut *(ptr as *mut Header).offset(-1) | ||
/// # Safety | ||
/// | ||
/// There must be a `Header` at `ptr.offset(-1)`. | ||
unsafe fn get_header<'a>(ptr: *mut u8) -> *mut Header { | ||
// SAFETY: the safety contract must be upheld by the caller | ||
unsafe { &mut *(ptr as *mut Header).offset(-1) } | ||
} | ||
|
||
/// # Safety | ||
/// | ||
/// `ptr`, once aligned, must have space for a Header at `ptr.offset(-1)`. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not a sufficient condition. It looks like regardless this function is wrong as it gets There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should I just inline the function and avoid the &mut? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change |
||
unsafe fn align_ptr(ptr: *mut u8, align: usize) -> *mut u8 { | ||
let aligned = ptr.add(align - (ptr as usize & (align - 1))); | ||
*get_header(aligned) = Header(ptr); | ||
aligned | ||
// SAFETY: the safety contract must be upheld by the caller | ||
carbotaniuman marked this conversation as resolved.
Show resolved
Hide resolved
|
||
unsafe { | ||
let aligned = ptr.add(align - (ptr as usize & (align - 1))); | ||
ptr::write(get_header(aligned), Header(ptr)); | ||
aligned | ||
} | ||
} | ||
|
||
#[inline] | ||
unsafe fn allocate_with_flags(layout: Layout, flags: c::DWORD) -> *mut u8 { | ||
if layout.align() <= MIN_ALIGN { | ||
return c::HeapAlloc(c::GetProcessHeap(), flags, layout.size()) as *mut u8; | ||
// SAFETY: `layout.size()` comes from `Layout` and is valid. | ||
return unsafe { c::HeapAlloc(c::GetProcessHeap(), flags, layout.size()) as *mut u8 }; | ||
} | ||
|
||
let size = layout.size() + layout.align(); | ||
let ptr = c::HeapAlloc(c::GetProcessHeap(), flags, size); | ||
if ptr.is_null() { ptr as *mut u8 } else { align_ptr(ptr as *mut u8, layout.align()) } | ||
let ptr = unsafe { | ||
// SAFETY: The caller must ensure that | ||
// `layout.size()` + `layout.align()` does not overflow. | ||
let size = layout.size() + layout.align(); | ||
c::HeapAlloc(c::GetProcessHeap(), flags, size) | ||
}; | ||
|
||
if ptr.is_null() { | ||
ptr as *mut u8 | ||
} else { | ||
// SAFETY: `ptr` is a valid pointer | ||
// with enough allocated space to store the header. | ||
unsafe { align_ptr(ptr as *mut u8, layout.align()) } | ||
} | ||
} | ||
|
||
// SAFETY: All methods implemented follow the contract rules defined | ||
// in `GlobalAlloc`. | ||
#[stable(feature = "alloc_system_type", since = "1.28.0")] | ||
unsafe impl GlobalAlloc for System { | ||
#[inline] | ||
unsafe fn alloc(&self, layout: Layout) -> *mut u8 { | ||
allocate_with_flags(layout, 0) | ||
// SAFETY: the safety contract for `allocate_with_flags` must be upheld by the caller. | ||
unsafe { allocate_with_flags(layout, 0) } | ||
} | ||
|
||
#[inline] | ||
unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { | ||
allocate_with_flags(layout, c::HEAP_ZERO_MEMORY) | ||
// SAFETY: the safety contract for `allocate_with_flags must be upheld by the caller. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is likely not sufficient. See e.g. #74477 for necessary commentary here; these comments should show that the function being called has preconditions equivalent to the trait. There are several more cases in this PR where you assert that the preconditions/safety contract of X must be upheld by the caller, please take a look at those and try to adjust them too. |
||
unsafe { allocate_with_flags(layout, c::HEAP_ZERO_MEMORY) } | ||
} | ||
|
||
#[inline] | ||
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { | ||
if layout.align() <= MIN_ALIGN { | ||
let err = c::HeapFree(c::GetProcessHeap(), 0, ptr as c::LPVOID); | ||
debug_assert!(err != 0, "Failed to free heap memory: {}", c::GetLastError()); | ||
} else { | ||
let header = get_header(ptr); | ||
let err = c::HeapFree(c::GetProcessHeap(), 0, header.0 as c::LPVOID); | ||
debug_assert!(err != 0, "Failed to free heap memory: {}", c::GetLastError()); | ||
} | ||
// SAFETY: HeapFree is safe if ptr was allocated by this allocator | ||
let err = unsafe { | ||
if layout.align() <= MIN_ALIGN { | ||
c::HeapFree(c::GetProcessHeap(), 0, ptr as c::LPVOID) | ||
} else { | ||
let header = get_header(ptr); | ||
c::HeapFree(c::GetProcessHeap(), 0, (*header).0 as c::LPVOID) | ||
} | ||
}; | ||
// SAFETY: `c::GetLastError()` cannot fail | ||
debug_assert!(err != 0, "Failed to free heap memory: {}", unsafe { c::GetLastError() }); | ||
carbotaniuman marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
#[inline] | ||
unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { | ||
// SAFETY: HeapReAlloc/realloc_fallback is safe if ptr was allocated by this allocator | ||
// and new_size is not 0. | ||
debug_assert_ne!(new_size, 0); | ||
if layout.align() <= MIN_ALIGN { | ||
c::HeapReAlloc(c::GetProcessHeap(), 0, ptr as c::LPVOID, new_size) as *mut u8 | ||
unsafe { c::HeapReAlloc(c::GetProcessHeap(), 0, ptr as c::LPVOID, new_size) as *mut u8 } | ||
} else { | ||
realloc_fallback(self, ptr, layout, new_size) | ||
unsafe { realloc_fallback(self, ptr, layout, new_size) } | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
#![deny(unsafe_op_in_unsafe_fn)] | ||
#![cfg(not(test))] | ||
|
||
use libc::{c_double, c_float}; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
#![deny(unsafe_op_in_unsafe_fn)] | ||
|
||
use crate::marker::PhantomData; | ||
use crate::slice; | ||
use crate::sys::c; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
#![deny(unsafe_op_in_unsafe_fn)] | ||
#![allow(missing_docs, nonstandard_style)] | ||
|
||
use crate::ffi::{OsStr, OsString}; | ||
|
Uh oh!
There was an error while loading. Please reload this page.