Skip to content

Commit c5e58f7

Browse files
committed
mitigate MSVC unsoundness by not emitting alignment attributes on win32-msvc targets
1 parent 8c35f4a commit c5e58f7

File tree

5 files changed

+29
-5
lines changed

5 files changed

+29
-5
lines changed

compiler/rustc_codegen_llvm/src/builder.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,9 @@ 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-
llvm::LLVMSetAlignment(load, align.bytes() as c_uint);
597+
if !self.cx().tcx.sess.target.has_unreliable_alignment() {
598+
llvm::LLVMSetAlignment(load, align.bytes() as c_uint);
599+
}
598600
load
599601
}
600602
}
@@ -809,7 +811,9 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
809811
let store = llvm::LLVMBuildStore(self.llbuilder, val, ptr);
810812
let align =
811813
if flags.contains(MemFlags::UNALIGNED) { 1 } else { align.bytes() as c_uint };
812-
llvm::LLVMSetAlignment(store, align);
814+
if !self.cx().tcx.sess.target.has_unreliable_alignment() {
815+
llvm::LLVMSetAlignment(store, align);
816+
}
813817
if flags.contains(MemFlags::VOLATILE) {
814818
llvm::LLVMSetVolatile(store, llvm::True);
815819
}

compiler/rustc_mir_transform/src/check_alignment.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ pub(super) struct CheckAlignment;
1111

1212
impl<'tcx> crate::MirPass<'tcx> for CheckAlignment {
1313
fn is_enabled(&self, sess: &Session) -> bool {
14-
// FIXME(#112480) MSVC and rustc disagree on minimum stack alignment on x86 Windows
15-
if sess.target.llvm_target == "i686-pc-windows-msvc" {
14+
if sess.target.has_unreliable_alignment() {
1615
return false;
1716
}
1817
sess.ub_checks()

compiler/rustc_target/src/callconv/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ pub struct ArgAttributes {
144144
/// (corresponding to LLVM's dereferenceable_or_null attributes, i.e., it is okay for this to be
145145
/// set on a null pointer, but all non-null pointers must be dereferenceable).
146146
pub pointee_size: Size,
147+
/// The minimum alignment of the pointee, if any.
147148
pub pointee_align: Option<Align>,
148149
}
149150

compiler/rustc_target/src/spec/mod.rs

+18
Original file line numberDiff line numberDiff line change
@@ -3602,6 +3602,24 @@ impl Target {
36023602
_ => return None,
36033603
})
36043604
}
3605+
3606+
/// Returns whether this target is known to have unreliable alignment:
3607+
/// native C code for the target fails to align some data to the degree
3608+
/// required by the C standard. We can't *really* do anything about that
3609+
/// since unsafe Rust code may assume alignment any time, but we can at least
3610+
/// inhibit some optimizations, and we suppress the alignment checks that
3611+
/// would detect this unsoundness.
3612+
///
3613+
/// Every `return true` here is still a soundness bug for that target.
3614+
pub fn has_unreliable_alignment(&self) -> bool {
3615+
// FIXME(#112480) MSVC on x86-32 is unsound and fails to properly align many types with
3616+
// more-than-4-byte-alignment on the stack.
3617+
if self.is_like_msvc && self.arch == "x86" {
3618+
return true;
3619+
}
3620+
3621+
false
3622+
}
36053623
}
36063624

36073625
/// Either a target tuple string or a path to a JSON file.

compiler/rustc_ty_utils/src/abi.rs

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

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

0 commit comments

Comments
 (0)