@@ -12,7 +12,7 @@ use crate::MemFlags;
12
12
use rustc_ast as ast;
13
13
use rustc_ast:: { InlineAsmOptions , InlineAsmTemplatePiece } ;
14
14
use rustc_hir:: lang_items:: LangItem ;
15
- use rustc_middle:: mir:: { self , AssertKind , SwitchTargets , UnwindTerminateReason } ;
15
+ use rustc_middle:: mir:: { self , AssertKind , SwitchTargets , UbCheckKind , UnwindTerminateReason } ;
16
16
use rustc_middle:: ty:: layout:: { HasTyCtxt , LayoutOf , ValidityRequirement } ;
17
17
use rustc_middle:: ty:: print:: { with_no_trimmed_paths, with_no_visible_paths} ;
18
18
use rustc_middle:: ty:: { self , Instance , Ty } ;
@@ -616,13 +616,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
616
616
// and `#[track_caller]` adds an implicit third argument.
617
617
( LangItem :: PanicBoundsCheck , vec ! [ index, len, location] )
618
618
}
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
- }
626
619
_ => {
627
620
let msg = bx. const_str ( msg. description ( ) ) ;
628
621
// 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> {
736
729
}
737
730
}
738
731
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
+
739
805
fn codegen_call_terminator (
740
806
& mut self ,
741
807
helper : TerminatorCodegenHelper < ' tcx > ,
@@ -1291,6 +1357,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
1291
1357
self . instance ,
1292
1358
mergeable_succ ( ) ,
1293
1359
) ,
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) ,
1294
1365
}
1295
1366
}
1296
1367
0 commit comments