Skip to content

Commit c1665e7

Browse files
committed
Apply #![deny(unsafe_op_in_unsafe_fn)] to sys/windows
1 parent 187b877 commit c1665e7

36 files changed

+283
-128
lines changed

library/std/src/sys/windows/alloc.rs

Lines changed: 54 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#![deny(unsafe_op_in_unsafe_fn)]
2+
13
use crate::alloc::{GlobalAlloc, Layout, System};
24
use crate::sys::c;
35
use crate::sys_common::alloc::{realloc_fallback, MIN_ALIGN};
@@ -6,56 +8,87 @@ use crate::sys_common::alloc::{realloc_fallback, MIN_ALIGN};
68
struct Header(*mut u8);
79

810
unsafe fn get_header<'a>(ptr: *mut u8) -> &'a mut Header {
9-
&mut *(ptr as *mut Header).offset(-1)
11+
// SAFETY: the safety contract must be upheld by the caller
12+
unsafe { &mut *(ptr as *mut Header).offset(-1) }
1013
}
1114

1215
unsafe fn align_ptr(ptr: *mut u8, align: usize) -> *mut u8 {
13-
let aligned = ptr.add(align - (ptr as usize & (align - 1)));
14-
*get_header(aligned) = Header(ptr);
15-
aligned
16+
// SAFETY: the safety contract must be upheld by the caller
17+
unsafe {
18+
let aligned = ptr.add(align - (ptr as usize & (align - 1)));
19+
*get_header(aligned) = Header(ptr);
20+
aligned
21+
}
1622
}
1723

1824
#[inline]
1925
unsafe fn allocate_with_flags(layout: Layout, flags: c::DWORD) -> *mut u8 {
2026
if layout.align() <= MIN_ALIGN {
21-
return c::HeapAlloc(c::GetProcessHeap(), flags, layout.size()) as *mut u8;
27+
// SAFETY: `layout.size()` comes from `Layout` and is valid.
28+
return unsafe { c::HeapAlloc(c::GetProcessHeap(), flags, layout.size()) as *mut u8 };
2229
}
2330

24-
let size = layout.size() + layout.align();
25-
let ptr = c::HeapAlloc(c::GetProcessHeap(), flags, size);
26-
if ptr.is_null() { ptr as *mut u8 } else { align_ptr(ptr as *mut u8, layout.align()) }
31+
let ptr = unsafe {
32+
// SAFETY: The caller must ensure that
33+
// `layout.size()` + `layout.size()` does not overflow.
34+
let size = layout.size() + layout.align();
35+
c::HeapAlloc(c::GetProcessHeap(), flags, size)
36+
};
37+
38+
if ptr.is_null() {
39+
ptr as *mut u8
40+
} else {
41+
// SAFETY: `ptr` is a valid pointer
42+
// with enough allocated space to store the header.
43+
unsafe { align_ptr(ptr as *mut u8, layout.align()) }
44+
}
2745
}
2846

47+
// SAFETY: All methods implemented follow the contract rules defined
48+
// in `GlobalAlloc`.
2949
#[stable(feature = "alloc_system_type", since = "1.28.0")]
3050
unsafe impl GlobalAlloc for System {
3151
#[inline]
3252
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
33-
allocate_with_flags(layout, 0)
53+
// SAFETY: the safety contract for `allocate_with_flags` must be upheld by the caller.
54+
unsafe { allocate_with_flags(layout, 0) }
3455
}
3556

3657
#[inline]
3758
unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
38-
allocate_with_flags(layout, c::HEAP_ZERO_MEMORY)
59+
// SAFETY: the safety contract for `allocate_with_flags must be upheld by the caller.
60+
unsafe { allocate_with_flags(layout, c::HEAP_ZERO_MEMORY) }
3961
}
4062

4163
#[inline]
4264
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
43-
if layout.align() <= MIN_ALIGN {
44-
let err = c::HeapFree(c::GetProcessHeap(), 0, ptr as c::LPVOID);
45-
debug_assert!(err != 0, "Failed to free heap memory: {}", c::GetLastError());
46-
} else {
47-
let header = get_header(ptr);
48-
let err = c::HeapFree(c::GetProcessHeap(), 0, header.0 as c::LPVOID);
49-
debug_assert!(err != 0, "Failed to free heap memory: {}", c::GetLastError());
65+
// SAFETY: HeapFree is safe if ptr was allocated by this allocator
66+
let err = unsafe {
67+
if layout.align() <= MIN_ALIGN {
68+
c::HeapFree(c::GetProcessHeap(), 0, ptr as c::LPVOID);
69+
} else {
70+
let header = get_header(ptr);
71+
c::HeapFree(c::GetProcessHeap(), 0, header.0 as c::LPVOID);
72+
}
5073
}
74+
debug_assert!(err != 0, "Failed to free heap memory: {}", c::GetLastError());
5175
}
5276

5377
#[inline]
5478
unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
55-
if layout.align() <= MIN_ALIGN {
56-
c::HeapReAlloc(c::GetProcessHeap(), 0, ptr as c::LPVOID, new_size) as *mut u8
57-
} else {
58-
realloc_fallback(self, ptr, layout, new_size)
79+
unsafe {
80+
if layout.align() <= MIN_ALIGN {
81+
// SAFETY: HeapReAlloc is safe if ptr was allocated by this allocator
82+
// and new_size is not 0.
83+
unsafe {
84+
c::HeapReAlloc(c::GetProcessHeap(), 0, ptr as c::LPVOID, new_size) as *mut u8
85+
}
86+
} else {
87+
// SAFETY: The safety contract for `realloc_fallback` must be upheld by the caller
88+
unsafe {
89+
realloc_fallback(self, ptr, layout, new_size)
90+
}
91+
}
5992
}
6093
}
6194
}

library/std/src/sys/windows/args.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![allow(dead_code)] // runtime init functions not used during testing
2+
#![deny(unsafe_op_in_unsafe_fn)]
23

34
#[cfg(test)]
45
mod tests;
@@ -52,11 +53,14 @@ unsafe fn parse_lp_cmd_line<F: Fn() -> OsString>(
5253
const TAB: u16 = '\t' as u16;
5354
const SPACE: u16 = ' ' as u16;
5455
let mut ret_val = Vec::new();
55-
if lp_cmd_line.is_null() || *lp_cmd_line == 0 {
56-
ret_val.push(exe_name());
57-
return ret_val;
58-
}
59-
let mut cmd_line = {
56+
57+
//SAFETY: the caller must supply a valid pointer
58+
let mut cmd_line = unsafe {
59+
if lp_cmd_line.is_null() || *lp_cmd_line == 0 {
60+
ret_val.push(exe_name());
61+
return ret_val;
62+
}
63+
6064
let mut end = 0;
6165
while *lp_cmd_line.offset(end) != 0 {
6266
end += 1;

library/std/src/sys/windows/c.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! C definitions used by libnative that don't belong in liblibc
22
33
#![allow(nonstandard_style)]
4+
#![deny(unsafe_op_in_unsafe_fn)]
45
#![cfg_attr(test, allow(dead_code))]
56
#![unstable(issue = "none", feature = "windows_c")]
67

library/std/src/sys/windows/cmath.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#![deny(unsafe_op_in_unsafe_fn)]
12
#![cfg(not(test))]
23

34
use libc::{c_double, c_float};

library/std/src/sys/windows/compat.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
//! manner we pay a semi-large one-time cost up front for detecting whether a
1212
//! function is available but afterwards it's just a load and a jump.
1313
14+
#![deny(unsafe_op_in_unsafe_fn)]
15+
1416
use crate::ffi::CString;
1517
use crate::sys::c;
1618

@@ -86,7 +88,9 @@ macro_rules! compat_fn {
8688
}
8789

8890
pub unsafe fn call($($argname: $argtype),*) -> $rettype {
89-
mem::transmute::<usize, F>(addr())($($argname),*)
91+
unsafe {
92+
mem::transmute::<usize, F>(addr())($($argname),*)
93+
}
9094
}
9195
}
9296

library/std/src/sys/windows/condvar.rs

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#![deny(unsafe_op_in_unsafe_fn)]
2+
13
use crate::cell::UnsafeCell;
24
use crate::sys::c;
35
use crate::sys::mutex::{self, Mutex};
@@ -23,17 +25,23 @@ impl Condvar {
2325

2426
#[inline]
2527
pub unsafe fn wait(&self, mutex: &Mutex) {
26-
let r = c::SleepConditionVariableSRW(self.inner.get(), mutex::raw(mutex), c::INFINITE, 0);
28+
// SAFETY: The caller must ensure that the condvar is not moved or copied
29+
let r = unsafe {
30+
c::SleepConditionVariableSRW(self.inner.get(), mutex::raw(mutex), c::INFINITE, 0)
31+
};
2732
debug_assert!(r != 0);
2833
}
2934

3035
pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
31-
let r = c::SleepConditionVariableSRW(
32-
self.inner.get(),
33-
mutex::raw(mutex),
34-
super::dur2timeout(dur),
35-
0,
36-
);
36+
// SAFETY: The caller must ensure that the condvar is not moved or copied
37+
let r = unsafe {
38+
c::SleepConditionVariableSRW(
39+
self.inner.get(),
40+
mutex::raw(mutex),
41+
super::dur2timeout(dur),
42+
0,
43+
)
44+
};
3745
if r == 0 {
3846
debug_assert_eq!(os::errno() as usize, c::ERROR_TIMEOUT as usize);
3947
false
@@ -44,12 +52,14 @@ impl Condvar {
4452

4553
#[inline]
4654
pub unsafe fn notify_one(&self) {
47-
c::WakeConditionVariable(self.inner.get())
55+
// SAFETY: The caller must ensure that the condvar is not moved or copied
56+
unsafe { c::WakeConditionVariable(self.inner.get()) }
4857
}
4958

5059
#[inline]
5160
pub unsafe fn notify_all(&self) {
52-
c::WakeAllConditionVariable(self.inner.get())
61+
// SAFETY: The caller must ensure that the condvar is not moved or copied
62+
unsafe { c::WakeAllConditionVariable(self.inner.get()) }
5363
}
5464

5565
pub unsafe fn destroy(&self) {

library/std/src/sys/windows/env.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#![deny(unsafe_op_in_unsafe_fn)]
2+
13
pub mod os {
24
pub const FAMILY: &str = "windows";
35
pub const OS: &str = "windows";

library/std/src/sys/windows/ext/ffi.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
//! [`collect`]: crate::iter::Iterator::collect
5151
//! [U+FFFD]: crate::char::REPLACEMENT_CHARACTER
5252
53+
#![deny(unsafe_op_in_unsafe_fn)]
5354
#![stable(feature = "rust1", since = "1.0.0")]
5455

5556
use crate::ffi::{OsStr, OsString};

library/std/src/sys/windows/ext/fs.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! Windows-specific extensions for the primitives in the `std::fs` module.
22
3+
#![deny(unsafe_op_in_unsafe_fn)]
34
#![stable(feature = "rust1", since = "1.0.0")]
45

56
use crate::fs::{self, Metadata, OpenOptions};

library/std/src/sys/windows/ext/io.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! Windows-specific extensions to general I/O primitives.
22
3+
#![deny(unsafe_op_in_unsafe_fn)]
34
#![stable(feature = "rust1", since = "1.0.0")]
45

56
use crate::fs;

0 commit comments

Comments
 (0)