Skip to content

Commit d4ce381

Browse files
committed
platform-support: mention the MSVC alignment issue
1 parent b37e0c1 commit d4ce381

File tree

7 files changed

+27
-18
lines changed

7 files changed

+27
-18
lines changed

Diff for: compiler/rustc_codegen_llvm/src/builder.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -594,9 +594,8 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
594594
fn load(&mut self, ty: &'ll Type, ptr: &'ll Value, align: Align) -> &'ll Value {
595595
unsafe {
596596
let load = llvm::LLVMBuildLoad2(self.llbuilder, ty, ptr, UNNAMED);
597-
if !self.cx().tcx.sess.target.has_unreliable_alignment() {
598-
llvm::LLVMSetAlignment(load, align.bytes() as c_uint);
599-
}
597+
let align = align.min(self.cx().tcx.sess.target.max_reliable_alignment());
598+
llvm::LLVMSetAlignment(load, align.bytes() as c_uint);
600599
load
601600
}
602601
}
@@ -809,11 +808,10 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
809808
assert_eq!(self.cx.type_kind(self.cx.val_ty(ptr)), TypeKind::Pointer);
810809
unsafe {
811810
let store = llvm::LLVMBuildStore(self.llbuilder, val, ptr);
811+
let align = align.min(self.cx().tcx.sess.target.max_reliable_alignment());
812812
let align =
813813
if flags.contains(MemFlags::UNALIGNED) { 1 } else { align.bytes() as c_uint };
814-
if !self.cx().tcx.sess.target.has_unreliable_alignment() {
815-
llvm::LLVMSetAlignment(store, align);
816-
}
814+
llvm::LLVMSetAlignment(store, align);
817815
if flags.contains(MemFlags::VOLATILE) {
818816
llvm::LLVMSetVolatile(store, llvm::True);
819817
}

Diff for: compiler/rustc_mir_transform/src/check_alignment.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use rustc_abi::Align;
12
use rustc_index::IndexVec;
23
use rustc_middle::mir::interpret::Scalar;
34
use rustc_middle::mir::visit::PlaceContext;
@@ -11,7 +12,7 @@ pub(super) struct CheckAlignment;
1112

1213
impl<'tcx> crate::MirPass<'tcx> for CheckAlignment {
1314
fn is_enabled(&self, sess: &Session) -> bool {
14-
if sess.target.has_unreliable_alignment() {
15+
if sess.target.max_reliable_alignment() < Align::MAX {
1516
return false;
1617
}
1718
sess.ub_checks()

Diff for: compiler/rustc_target/src/spec/mod.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ use std::path::{Path, PathBuf};
4242
use std::str::FromStr;
4343
use std::{fmt, io};
4444

45-
use rustc_abi::{Endian, ExternAbi, Integer, Size, TargetDataLayout, TargetDataLayoutErrors};
45+
use rustc_abi::{
46+
Align, Endian, ExternAbi, Integer, Size, TargetDataLayout, TargetDataLayoutErrors,
47+
};
4648
use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
4749
use rustc_fs_util::try_canonicalize;
4850
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
@@ -3610,11 +3612,15 @@ impl Target {
36103612
/// inhibit some optimizations, and we suppress the alignment checks that
36113613
/// would detect this unsoundness.
36123614
///
3613-
/// Every target that returns `true` here is still has a soundness bug.
3614-
pub fn has_unreliable_alignment(&self) -> bool {
3615+
/// Every target that returns less than `Align::MAX` here is still has a soundness bug.
3616+
pub fn max_reliable_alignment(&self) -> Align {
36153617
// FIXME(#112480) MSVC on x86-32 is unsound and fails to properly align many types with
36163618
// more-than-4-byte-alignment on the stack.
3617-
self.is_like_msvc && self.arch == "x86"
3619+
if self.is_like_msvc && self.arch == "x86" {
3620+
Align::from_bytes(4).unwrap()
3621+
} else {
3622+
Align::MAX
3623+
}
36183624
}
36193625
}
36203626

Diff for: compiler/rustc_ty_utils/src/abi.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -347,9 +347,8 @@ fn adjust_for_rust_scalar<'tcx>(
347347
None
348348
};
349349
if let Some(kind) = kind {
350-
if !cx.tcx().sess.target.has_unreliable_alignment() {
351-
attrs.pointee_align = Some(pointee.align);
352-
}
350+
attrs.pointee_align =
351+
Some(pointee.align.min(cx.tcx().sess.target.max_reliable_alignment()));
353352

354353
// `Box` are not necessarily dereferenceable for the entire duration of the function as
355354
// they can be deallocated at any time. Same for non-frozen shared references (see

Diff for: src/doc/rustc/src/platform-support.md

+5-3
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ target | notes
3535
[`aarch64-apple-darwin`](platform-support/apple-darwin.md) | ARM64 macOS (11.0+, Big Sur+)
3636
`aarch64-unknown-linux-gnu` | ARM64 Linux (kernel 4.1, glibc 2.17+)
3737
`i686-pc-windows-gnu` | 32-bit MinGW (Windows 10+, Windows Server 2016+, Pentium 4) [^x86_32-floats-return-ABI]
38-
`i686-pc-windows-msvc` | 32-bit MSVC (Windows 10+, Windows Server 2016+, Pentium 4) [^x86_32-floats-return-ABI]
38+
`i686-pc-windows-msvc` | 32-bit MSVC (Windows 10+, Windows Server 2016+, Pentium 4) [^x86_32-floats-return-ABI] [^win32-msvc-alignment]
3939
`i686-unknown-linux-gnu` | 32-bit Linux (kernel 3.2+, glibc 2.17+, Pentium 4) [^x86_32-floats-return-ABI]
4040
[`x86_64-apple-darwin`](platform-support/apple-darwin.md) | 64-bit macOS (10.12+, Sierra+)
4141
`x86_64-pc-windows-gnu` | 64-bit MinGW (Windows 10+, Windows Server 2016+)
@@ -44,6 +44,8 @@ target | notes
4444

4545
[^x86_32-floats-return-ABI]: Due to limitations of the C ABI, floating-point support on `i686` targets is non-compliant: floating-point return values are passed via an x87 register, so NaN payload bits can be lost. Functions with the default Rust ABI are not affected. See [issue #115567][x86-32-float-return-issue].
4646

47+
[^win32-msvc-alignment]: Due to non-standard behavior of MSVC, native C code on this target can cause types with an alignment of more than 4 bytes to be incorrectly aligned to only 4 bytes (this affects, e.g., `u64` and `i64`). Rust applies some mitigations to reduce the impact of this issue, but this can still cause unsoundness due to unsafe code that (correctly) assumes that references are always properly aligned. See [issue #112480](https://github.com/rust-lang/rust/issues/112480).
48+
4749
[77071]: https://github.com/rust-lang/rust/issues/77071
4850
[x86-32-float-return-issue]: https://github.com/rust-lang/rust/issues/115567
4951

@@ -317,9 +319,9 @@ target | std | host | notes
317319
[`i686-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | NetBSD/i386 (Pentium 4) [^x86_32-floats-return-ABI]
318320
[`i686-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | 32-bit OpenBSD (Pentium 4) [^x86_32-floats-return-ABI]
319321
`i686-uwp-windows-gnu` | ✓ | | [^x86_32-floats-return-ABI]
320-
[`i686-uwp-windows-msvc`](platform-support/uwp-windows-msvc.md) | ✓ | | [^x86_32-floats-return-ABI]
322+
[`i686-uwp-windows-msvc`](platform-support/uwp-windows-msvc.md) | ✓ | | [^x86_32-floats-return-ABI] [^win32-msvc-alignment]
321323
[`i686-win7-windows-gnu`](platform-support/win7-windows-gnu.md) | ✓ | | 32-bit Windows 7 support [^x86_32-floats-return-ABI]
322-
[`i686-win7-windows-msvc`](platform-support/win7-windows-msvc.md) | ✓ | | 32-bit Windows 7 support [^x86_32-floats-return-ABI]
324+
[`i686-win7-windows-msvc`](platform-support/win7-windows-msvc.md) | ✓ | | 32-bit Windows 7 support [^x86_32-floats-return-ABI] [^win32-msvc-alignment]
323325
[`i686-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | [^x86_32-floats-return-ABI]
324326
[`loongarch64-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | | LoongArch64 OpenHarmony
325327
[`m68k-unknown-linux-gnu`](platform-support/m68k-unknown-linux-gnu.md) | ? | | Motorola 680x0 Linux

Diff for: tests/codegen/align-struct.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//@ compile-flags: -C no-prepopulate-passes -Z mir-opt-level=0
2-
//
2+
// 32bit MSVC does not align things properly so we suppress high alignment annotations (#112480)
3+
//@ ignore-msvc
34

45
#![crate_type = "lib"]
56

Diff for: tests/codegen/issues/issue-56927.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
//@ compile-flags: -C no-prepopulate-passes
2+
// 32bit MSVC does not align things properly so we suppress high alignment annotations (#112480)
3+
//@ ignore-msvc
24

35
#![crate_type = "rlib"]
46

0 commit comments

Comments
 (0)