@@ -12,7 +12,7 @@ use crate::MemFlags;
1212use rustc_ast as ast;
1313use rustc_ast:: { InlineAsmOptions , InlineAsmTemplatePiece } ;
1414use rustc_hir:: lang_items:: LangItem ;
15- use rustc_middle:: mir:: { self , AssertKind , SwitchTargets , UnwindTerminateReason } ;
15+ use rustc_middle:: mir:: { self , AssertKind , SwitchTargets , UbCheckKind , UnwindTerminateReason } ;
1616use rustc_middle:: ty:: layout:: { HasTyCtxt , LayoutOf , ValidityRequirement } ;
1717use rustc_middle:: ty:: print:: { with_no_trimmed_paths, with_no_visible_paths} ;
1818use rustc_middle:: ty:: { self , Instance , Ty } ;
@@ -616,13 +616,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
616616 // and `#[track_caller]` adds an implicit third argument.
617617 ( LangItem :: PanicBoundsCheck , vec ! [ index, len, location] )
618618 }
619- AssertKind :: MisalignedPointerDereference { ref required, ref found } => {
620- let required = self . codegen_operand ( bx, required) . immediate ( ) ;
621- let found = self . codegen_operand ( bx, found) . immediate ( ) ;
622- // It's `fn panic_misaligned_pointer_dereference(required: usize, found: usize)`,
623- // and `#[track_caller]` adds an implicit third argument.
624- ( LangItem :: PanicMisalignedPointerDereference , vec ! [ required, found, location] )
625- }
626619 _ => {
627620 let msg = bx. const_str ( msg. description ( ) ) ;
628621 // It's `pub fn panic(expr: &str)`, with the wide reference being passed
@@ -736,6 +729,79 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
736729 }
737730 }
738731
732+ fn codegen_alignment_check (
733+ & mut self ,
734+ helper : & TerminatorCodegenHelper < ' tcx > ,
735+ bx : & mut Bx ,
736+ pointer : & mir:: Operand < ' tcx > ,
737+ source_info : mir:: SourceInfo ,
738+ target : mir:: BasicBlock ,
739+ ) -> MergingSucc {
740+ let span = source_info. span ;
741+ let pointer = self . codegen_operand ( bx, pointer) ;
742+ let pointee_ty = pointer. layout . ty . builtin_deref ( true ) . unwrap ( ) ;
743+ let pointee_layout = bx. layout_of ( pointee_ty. ty ) ;
744+
745+ let mk_usize = |v : u64 | {
746+ let layout = bx. layout_of ( bx. tcx ( ) . types . usize ) ;
747+ let rustc_target:: abi:: Abi :: Scalar ( abi) = layout. abi else { unreachable ! ( ) } ;
748+ let v = rustc_middle:: mir:: interpret:: Scalar :: from_target_usize ( v, & bx. tcx ( ) ) ;
749+ bx. scalar_to_backend ( v, abi, bx. cx ( ) . type_isize ( ) )
750+ } ;
751+
752+ let align = pointee_layout. align . abi . bytes ( ) ;
753+ let mask = mk_usize ( align - 1 ) ;
754+ let zero = mk_usize ( 0 ) ;
755+ let required = mk_usize ( align) ;
756+
757+ let ptr_imm = match pointer. val {
758+ crate :: mir:: OperandValue :: Immediate ( imm) => imm,
759+ crate :: mir:: OperandValue :: Pair ( ptr, _) => ptr,
760+ _ => {
761+ unreachable ! ( "{pointer:?}" ) ;
762+ }
763+ } ;
764+ let int_imm = bx. ptrtoint ( ptr_imm, bx. cx ( ) . type_isize ( ) ) ;
765+
766+ let masked = bx. and ( int_imm, mask) ;
767+
768+ let is_zero = bx. icmp (
769+ crate :: base:: bin_op_to_icmp_predicate ( mir:: BinOp :: Eq . to_hir_binop ( ) , false ) ,
770+ masked,
771+ zero,
772+ ) ;
773+
774+ let lltarget = helper. llbb_with_cleanup ( self , target) ;
775+ let panic_block = bx. append_sibling_block ( "panic" ) ;
776+
777+ bx. cond_br ( is_zero, lltarget, panic_block) ;
778+
779+ bx. switch_to_block ( panic_block) ;
780+ self . set_debug_loc ( bx, source_info) ;
781+
782+ let location = self . get_caller_location ( bx, source_info) . immediate ( ) ;
783+
784+ let found = int_imm;
785+
786+ let ( lang_item, args) =
787+ ( LangItem :: PanicMisalignedPointerDereference , vec ! [ required, found, location] ) ;
788+
789+ let ( fn_abi, llfn) = common:: build_langcall ( bx, Some ( span) , lang_item) ;
790+ let merging_succ = helper. do_call (
791+ self ,
792+ bx,
793+ fn_abi,
794+ llfn,
795+ & args,
796+ None ,
797+ mir:: UnwindAction :: Unreachable ,
798+ & [ ] ,
799+ false ,
800+ ) ;
801+ assert_eq ! ( merging_succ, MergingSucc :: False ) ;
802+ MergingSucc :: False
803+ }
804+
739805 fn codegen_call_terminator (
740806 & mut self ,
741807 helper : TerminatorCodegenHelper < ' tcx > ,
@@ -1291,6 +1357,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
12911357 self . instance ,
12921358 mergeable_succ ( ) ,
12931359 ) ,
1360+
1361+ mir:: TerminatorKind :: UbCheck {
1362+ target,
1363+ kind : UbCheckKind :: PointerAlignment { ref pointer } ,
1364+ } => self . codegen_alignment_check ( & helper, bx, pointer, terminator. source_info , target) ,
12941365 }
12951366 }
12961367
0 commit comments