Skip to content

Commit 5c3490c

Browse files
committed
Replace AlignedAs with a more specific Align8 type
1 parent d9c760d commit 5c3490c

File tree

3 files changed

+20
-52
lines changed

3 files changed

+20
-52
lines changed

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

+14-13
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::slice;
1111
use crate::sync::Arc;
1212
use crate::sys::handle::Handle;
1313
use crate::sys::time::SystemTime;
14-
use crate::sys::{c, cvt, AlignedAs};
14+
use crate::sys::{c, cvt, Align8};
1515
use crate::sys_common::{AsInner, FromInner, IntoInner};
1616
use crate::thread;
1717

@@ -47,9 +47,6 @@ pub struct ReadDir {
4747
first: Option<c::WIN32_FIND_DATAW>,
4848
}
4949

50-
type AlignedReparseBuf =
51-
AlignedAs<c::REPARSE_DATA_BUFFER, [u8; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE]>;
52-
5350
struct FindNextFileHandle(c::HANDLE);
5451

5552
unsafe impl Send for FindNextFileHandle {}
@@ -329,7 +326,7 @@ impl File {
329326
cvt(c::GetFileInformationByHandle(self.handle.as_raw_handle(), &mut info))?;
330327
let mut reparse_tag = 0;
331328
if info.dwFileAttributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0 {
332-
let mut b = AlignedReparseBuf::new([0u8; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE]);
329+
let mut b = Align8([0u8; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE]);
333330
if let Ok((_, buf)) = self.reparse_point(&mut b) {
334331
reparse_tag = (*buf).ReparseTag;
335332
}
@@ -392,7 +389,7 @@ impl File {
392389
attr.file_size = info.AllocationSize as u64;
393390
attr.number_of_links = Some(info.NumberOfLinks);
394391
if attr.file_type().is_reparse_point() {
395-
let mut b = AlignedReparseBuf::new([0; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE]);
392+
let mut b = Align8([0; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE]);
396393
if let Ok((_, buf)) = self.reparse_point(&mut b) {
397394
attr.reparse_tag = (*buf).ReparseTag;
398395
}
@@ -466,28 +463,32 @@ impl File {
466463
// avoid narrowing provenance to the actual `REPARSE_DATA_BUFFER`.
467464
fn reparse_point(
468465
&self,
469-
space: &mut AlignedReparseBuf,
466+
space: &mut Align8<[u8]>,
470467
) -> io::Result<(c::DWORD, *const c::REPARSE_DATA_BUFFER)> {
471468
unsafe {
472469
let mut bytes = 0;
473470
cvt({
471+
// Grab this in advance to avoid it invalidating the pointer
472+
// we get from `space.0.as_mut_ptr()`.
473+
let len = space.0.len();
474474
c::DeviceIoControl(
475475
self.handle.as_raw_handle(),
476476
c::FSCTL_GET_REPARSE_POINT,
477477
ptr::null_mut(),
478478
0,
479-
space.value.as_mut_ptr() as *mut _,
480-
space.value.len() as c::DWORD,
479+
space.0.as_mut_ptr().cast(),
480+
len as c::DWORD,
481481
&mut bytes,
482482
ptr::null_mut(),
483483
)
484484
})?;
485-
Ok((bytes, space.value.as_ptr().cast::<c::REPARSE_DATA_BUFFER>()))
485+
const _: () = assert!(core::mem::align_of::<c::REPARSE_DATA_BUFFER>() <= 8);
486+
Ok((bytes, space.0.as_ptr().cast::<c::REPARSE_DATA_BUFFER>()))
486487
}
487488
}
488489

489490
fn readlink(&self) -> io::Result<PathBuf> {
490-
let mut space = AlignedReparseBuf::new([0u8; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE]);
491+
let mut space = Align8([0u8; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE]);
491492
let (_bytes, buf) = self.reparse_point(&mut space)?;
492493
unsafe {
493494
let (path_buffer, subst_off, subst_len, relative) = match (*buf).ReparseTag {
@@ -1345,8 +1346,8 @@ fn symlink_junction_inner(original: &Path, junction: &Path) -> io::Result<()> {
13451346
let h = f.as_inner().as_raw_handle();
13461347

13471348
unsafe {
1348-
let mut data = AlignedReparseBuf::new([0u8; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE]);
1349-
let data_ptr = data.value.as_mut_ptr();
1349+
let mut data = Align8([0u8; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE]);
1350+
let data_ptr = data.0.as_mut_ptr();
13501351
let db = data_ptr.cast::<c::REPARSE_MOUNTPOINT_DATA_BUFFER>();
13511352
let buf = ptr::addr_of_mut!((*db).ReparseTarget).cast::<c::WCHAR>();
13521353
let mut i = 0;

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

+6-21
Original file line numberDiff line numberDiff line change
@@ -330,25 +330,10 @@ pub fn abort_internal() -> ! {
330330
crate::intrinsics::abort();
331331
}
332332

333-
/// Used for some win32 buffers which are stack allocated, for example:
334-
/// `AlignedAs<c::REPARSE_DATA_BUFFER, [u8; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE]>`
335-
#[repr(C)]
333+
/// Align the inner value to 8 bytes.
334+
///
335+
/// This is enough for almost all of the buffers we're likely to work with in
336+
/// the Windows APIs we use.
337+
#[repr(C, align(8))]
336338
#[derive(Copy, Clone)]
337-
pub struct AlignedAs<Aligner, Alignee: ?Sized> {
338-
/// Use `[Aligner; 0]` as a sort of `PhantomAlignNextField<Aligner>`. This
339-
/// is a bit of a hack, and could break (in a way that's caught by tests) if
340-
/// #81996 is fixed.
341-
aligner: [Aligner; 0],
342-
/// The aligned value. Public rather than exposed via accessors so that if
343-
/// needed it can be used with `addr_of` and such (also, this is less code).
344-
pub value: Alignee,
345-
}
346-
347-
impl<Aligner, Alignee> AlignedAs<Aligner, Alignee> {
348-
// This is frequently used with large stack buffers, so force-inline to
349-
// try and avoid using 2x as much stack space in debug builds.
350-
#[inline(always)]
351-
pub const fn new(value: Alignee) -> Self {
352-
Self { aligner: [], value }
353-
}
354-
}
339+
pub(crate) struct Align8<T: ?Sized>(pub T);

library/std/src/sys/windows/os/tests.rs

-18
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,3 @@ fn ntstatus_error() {
1111
.contains("FormatMessageW() returned error")
1212
);
1313
}
14-
15-
#[test]
16-
fn smoketest_aligned_as() {
17-
use crate::{
18-
mem::{align_of, size_of},
19-
ptr::addr_of,
20-
sys::{c, AlignedAs},
21-
};
22-
type AlignedReparseBuf =
23-
AlignedAs<c::REPARSE_DATA_BUFFER, [u8; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE]>;
24-
assert!(size_of::<AlignedReparseBuf>() >= c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
25-
assert_eq!(align_of::<AlignedReparseBuf>(), align_of::<c::REPARSE_DATA_BUFFER>());
26-
let a = AlignedReparseBuf::new([0u8; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE]);
27-
// Quick and dirty offsetof check.
28-
assert_eq!(addr_of!(a).cast::<u8>(), addr_of!(a.value).cast::<u8>());
29-
// Smoke check that it's actually aligned.
30-
assert!(addr_of!(a.value).is_aligned_to(align_of::<c::REPARSE_DATA_BUFFER>()));
31-
}

0 commit comments

Comments
 (0)