diff options
Diffstat (limited to 'compiler/rustc_mir_transform/src')
| -rw-r--r-- | compiler/rustc_mir_transform/src/check_alignment.rs | 30 | 
1 files changed, 27 insertions, 3 deletions
| diff --git a/compiler/rustc_mir_transform/src/check_alignment.rs b/compiler/rustc_mir_transform/src/check_alignment.rs index 3991f1b98cd..5115583f37c 100644 --- a/compiler/rustc_mir_transform/src/check_alignment.rs +++ b/compiler/rustc_mir_transform/src/check_alignment.rs @@ -12,9 +12,6 @@ pub(super) struct CheckAlignment; impl<'tcx> crate::MirPass<'tcx> for CheckAlignment { fn is_enabled(&self, sess: &Session) -> bool { - if sess.target.max_reliable_alignment() < Align::MAX { - return false; - } sess.ub_checks() } @@ -87,6 +84,33 @@ fn insert_alignment_check<'tcx>( ))), }); + // If this target does not have reliable alignment, further limit the mask by anding it with + // the mask for the highest reliable alignment. + #[allow(irrefutable_let_patterns)] + if let max_align = tcx.sess.target.max_reliable_alignment() + && max_align < Align::MAX + { + let max_mask = max_align.bytes() - 1; + let max_mask = Operand::Constant(Box::new(ConstOperand { + span: source_info.span, + user_ty: None, + const_: Const::Val( + ConstValue::Scalar(Scalar::from_target_usize(max_mask, &tcx)), + tcx.types.usize, + ), + })); + stmts.push(Statement { + source_info, + kind: StatementKind::Assign(Box::new(( + alignment_mask, + Rvalue::BinaryOp( + BinOp::BitAnd, + Box::new((Operand::Copy(alignment_mask), max_mask)), + ), + ))), + }); + } + // BitAnd the alignment mask with the pointer let alignment_bits = local_decls.push(LocalDecl::with_source_info(tcx.types.usize, source_info)).into(); | 
