1- use std:: convert:: TryFrom ;
2-
31use log:: trace;
42
53use rustc_middle:: { mir, ty:: Ty } ;
6- use rustc_target:: abi:: { LayoutOf , Size } ;
74
85use crate :: * ;
96
@@ -16,13 +13,6 @@ pub trait EvalContextExt<'tcx> {
1613 ) -> InterpResult < ' tcx , ( Scalar < Tag > , bool , Ty < ' tcx > ) > ;
1714
1815 fn ptr_eq ( & self , left : Scalar < Tag > , right : Scalar < Tag > ) -> InterpResult < ' tcx , bool > ;
19-
20- fn pointer_offset_inbounds (
21- & self ,
22- ptr : Scalar < Tag > ,
23- pointee_ty : Ty < ' tcx > ,
24- offset : i64 ,
25- ) -> InterpResult < ' tcx , Scalar < Tag > > ;
2616}
2717
2818impl < ' mir , ' tcx > EvalContextExt < ' tcx > for super :: MiriEvalContext < ' mir , ' tcx > {
@@ -71,7 +61,7 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
7161 Offset => {
7262 let pointee_ty =
7363 left. layout . ty . builtin_deref ( true ) . expect ( "Offset called on non-ptr type" ) . ty ;
74- let ptr = self . pointer_offset_inbounds (
64+ let ptr = self . ptr_offset_inbounds (
7565 left. to_scalar ( ) ?,
7666 pointee_ty,
7767 right. to_scalar ( ) ?. to_machine_isize ( self ) ?,
@@ -91,38 +81,4 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
9181 let right = self . force_bits ( right, size) ?;
9282 Ok ( left == right)
9383 }
94-
95- /// Raises an error if the offset moves the pointer outside of its allocation.
96- /// For integers, we consider each of them their own tiny allocation of size 0,
97- /// so offset-by-0 is okay for them -- except for NULL, which we rule out entirely.
98- fn pointer_offset_inbounds (
99- & self ,
100- ptr : Scalar < Tag > ,
101- pointee_ty : Ty < ' tcx > ,
102- offset : i64 ,
103- ) -> InterpResult < ' tcx , Scalar < Tag > > {
104- let pointee_size = i64:: try_from ( self . layout_of ( pointee_ty) ?. size . bytes ( ) ) . unwrap ( ) ;
105- let offset = offset. checked_mul ( pointee_size) . ok_or_else ( || {
106- err_ub_format ! ( "overflow during offset comutation for inbounds pointer arithmetic" )
107- } ) ?;
108- // We do this first, to rule out overflows.
109- let offset_ptr = ptr. ptr_signed_offset ( offset, self ) ?;
110- // What we need to check is that starting at `min(ptr, offset_ptr)`,
111- // we could do an access of size `abs(offset)`. Alignment does not matter.
112- let ( min_ptr, abs_offset) = if offset >= 0 {
113- ( ptr, u64:: try_from ( offset) . unwrap ( ) )
114- } else {
115- // Negative offset.
116- // If the negation overflows, the result will be negative so the try_from will fail.
117- ( offset_ptr, u64:: try_from ( -offset) . unwrap ( ) )
118- } ;
119- self . memory . check_ptr_access_align (
120- min_ptr,
121- Size :: from_bytes ( abs_offset) ,
122- None ,
123- CheckInAllocMsg :: InboundsTest ,
124- ) ?;
125- // That's it!
126- Ok ( offset_ptr)
127- }
12884}
0 commit comments