@@ -4,7 +4,7 @@ use rustc_middle::mir::*;
44use rustc_middle:: ty:: { Ty , TyCtxt } ;
55use rustc_session:: Session ;
66
7- use crate :: check_pointers:: check_pointers;
7+ use crate :: check_pointers:: { PointerCheck , check_pointers} ;
88
99pub ( super ) struct CheckAlignment ;
1010
@@ -24,35 +24,33 @@ impl<'tcx> crate::MirPass<'tcx> for CheckAlignment {
2424 }
2525}
2626
27+ /// Inserts the actual alignment check's logic. Returns a
28+ /// [AssertKind::MisalignedPointerDereference] on failure.
2729fn insert_alignment_check < ' tcx > (
2830 tcx : TyCtxt < ' tcx > ,
29- local_decls : & mut IndexVec < Local , LocalDecl < ' tcx > > ,
30- block_data : & mut BasicBlockData < ' tcx > ,
3131 pointer : Place < ' tcx > ,
3232 pointee_ty : Ty < ' tcx > ,
33+ local_decls : & mut IndexVec < Local , LocalDecl < ' tcx > > ,
34+ stmts : & mut Vec < Statement < ' tcx > > ,
3335 source_info : SourceInfo ,
34- new_block : BasicBlock ,
35- ) {
36- // Cast the pointer to a *const ()
36+ ) -> PointerCheck < ' tcx > {
37+ // Cast the pointer to a *const ().
3738 let const_raw_ptr = Ty :: new_imm_ptr ( tcx, tcx. types . unit ) ;
3839 let rvalue = Rvalue :: Cast ( CastKind :: PtrToPtr , Operand :: Copy ( pointer) , const_raw_ptr) ;
3940 let thin_ptr = local_decls. push ( LocalDecl :: with_source_info ( const_raw_ptr, source_info) ) . into ( ) ;
40- block_data
41- . statements
41+ stmts
4242 . push ( Statement { source_info, kind : StatementKind :: Assign ( Box :: new ( ( thin_ptr, rvalue) ) ) } ) ;
4343
44- // Transmute the pointer to a usize (equivalent to `ptr.addr()`)
44+ // Transmute the pointer to a usize (equivalent to `ptr.addr()`).
4545 let rvalue = Rvalue :: Cast ( CastKind :: Transmute , Operand :: Copy ( thin_ptr) , tcx. types . usize ) ;
4646 let addr = local_decls. push ( LocalDecl :: with_source_info ( tcx. types . usize , source_info) ) . into ( ) ;
47- block_data
48- . statements
49- . push ( Statement { source_info, kind : StatementKind :: Assign ( Box :: new ( ( addr, rvalue) ) ) } ) ;
47+ stmts. push ( Statement { source_info, kind : StatementKind :: Assign ( Box :: new ( ( addr, rvalue) ) ) } ) ;
5048
5149 // Get the alignment of the pointee
5250 let alignment =
5351 local_decls. push ( LocalDecl :: with_source_info ( tcx. types . usize , source_info) ) . into ( ) ;
5452 let rvalue = Rvalue :: NullaryOp ( NullOp :: AlignOf , pointee_ty) ;
55- block_data . statements . push ( Statement {
53+ stmts . push ( Statement {
5654 source_info,
5755 kind : StatementKind :: Assign ( Box :: new ( ( alignment, rvalue) ) ) ,
5856 } ) ;
@@ -65,7 +63,7 @@ fn insert_alignment_check<'tcx>(
6563 user_ty : None ,
6664 const_ : Const :: Val ( ConstValue :: Scalar ( Scalar :: from_target_usize ( 1 , & tcx) ) , tcx. types . usize ) ,
6765 } ) ) ;
68- block_data . statements . push ( Statement {
66+ stmts . push ( Statement {
6967 source_info,
7068 kind : StatementKind :: Assign ( Box :: new ( (
7169 alignment_mask,
@@ -76,7 +74,7 @@ fn insert_alignment_check<'tcx>(
7674 // BitAnd the alignment mask with the pointer
7775 let alignment_bits =
7876 local_decls. push ( LocalDecl :: with_source_info ( tcx. types . usize , source_info) ) . into ( ) ;
79- block_data . statements . push ( Statement {
77+ stmts . push ( Statement {
8078 source_info,
8179 kind : StatementKind :: Assign ( Box :: new ( (
8280 alignment_bits,
@@ -94,29 +92,21 @@ fn insert_alignment_check<'tcx>(
9492 user_ty : None ,
9593 const_ : Const :: Val ( ConstValue :: Scalar ( Scalar :: from_target_usize ( 0 , & tcx) ) , tcx. types . usize ) ,
9694 } ) ) ;
97- block_data . statements . push ( Statement {
95+ stmts . push ( Statement {
9896 source_info,
9997 kind : StatementKind :: Assign ( Box :: new ( (
10098 is_ok,
10199 Rvalue :: BinaryOp ( BinOp :: Eq , Box :: new ( ( Operand :: Copy ( alignment_bits) , zero. clone ( ) ) ) ) ,
102100 ) ) ) ,
103101 } ) ;
104102
105- // Set this block's terminator to our assert, continuing to new_block if we pass
106- block_data. terminator = Some ( Terminator {
107- source_info,
108- kind : TerminatorKind :: Assert {
109- cond : Operand :: Copy ( is_ok) ,
110- expected : true ,
111- target : new_block,
112- msg : Box :: new ( AssertKind :: MisalignedPointerDereference {
113- required : Operand :: Copy ( alignment) ,
114- found : Operand :: Copy ( addr) ,
115- } ) ,
116- // This calls panic_misaligned_pointer_dereference, which is #[rustc_nounwind].
117- // We never want to insert an unwind into unsafe code, because unwinding could
118- // make a failing UB check turn into much worse UB when we start unwinding.
119- unwind : UnwindAction :: Unreachable ,
120- } ,
121- } ) ;
103+ // Emit a check that asserts on the alignment and otherwise triggers a
104+ // AssertKind::MisalignedPointerDereference.
105+ PointerCheck {
106+ cond : Operand :: Copy ( is_ok) ,
107+ assert_kind : Box :: new ( AssertKind :: MisalignedPointerDereference {
108+ required : Operand :: Copy ( alignment) ,
109+ found : Operand :: Copy ( addr) ,
110+ } ) ,
111+ }
122112}
0 commit comments