@@ -7,7 +7,7 @@ use rustc_middle::{bug, mir, span_bug};
7
7
use rustc_span:: symbol:: sym;
8
8
use tracing:: trace;
9
9
10
- use super :: { err_ub , throw_ub, ImmTy , InterpCx , Machine , MemPlaceMeta } ;
10
+ use super :: { throw_ub, ImmTy , InterpCx , Machine , MemPlaceMeta } ;
11
11
12
12
impl < ' tcx , M : Machine < ' tcx > > InterpCx < ' tcx , M > {
13
13
fn three_way_compare < T : Ord > ( & self , lhs : T , rhs : T ) -> ImmTy < ' tcx , M :: Provenance > {
@@ -298,17 +298,23 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
298
298
// Pointer ops that are always supported.
299
299
Offset => {
300
300
let ptr = left. to_scalar ( ) . to_pointer ( self ) ?;
301
- let offset_count = right. to_scalar ( ) . to_target_isize ( self ) ?;
302
301
let pointee_ty = left. layout . ty . builtin_deref ( true ) . unwrap ( ) ;
302
+ let pointee_layout = self . layout_of ( pointee_ty) ?;
303
+ assert ! ( pointee_layout. abi. is_sized( ) ) ;
303
304
304
305
// We cannot overflow i64 as a type's size must be <= isize::MAX.
305
- let pointee_size = i64:: try_from ( self . layout_of ( pointee_ty) ?. size . bytes ( ) ) . unwrap ( ) ;
306
- // The computed offset, in bytes, must not overflow an isize.
307
- // `checked_mul` enforces a too small bound, but no actual allocation can be big enough for
308
- // the difference to be noticeable.
309
- let offset_bytes =
310
- offset_count. checked_mul ( pointee_size) . ok_or ( err_ub ! ( PointerArithOverflow ) ) ?;
306
+ let pointee_size = i64:: try_from ( pointee_layout. size . bytes ( ) ) . unwrap ( ) ;
307
+ let pointee_size = ImmTy :: from_int ( pointee_size, right. layout ) ;
308
+ // Multiply element size and element count.
309
+ let ( val, overflowed) = self
310
+ . binary_op ( mir:: BinOp :: MulWithOverflow , right, & pointee_size) ?
311
+ . to_scalar_pair ( ) ;
312
+ // This must not overflow.
313
+ if overflowed. to_bool ( ) ? {
314
+ throw_ub ! ( PointerArithOverflow )
315
+ }
311
316
317
+ let offset_bytes = val. to_target_isize ( self ) ?;
312
318
let offset_ptr = self . ptr_offset_inbounds ( ptr, offset_bytes) ?;
313
319
Ok ( ImmTy :: from_scalar ( Scalar :: from_maybe_pointer ( offset_ptr, self ) , left. layout ) )
314
320
}
0 commit comments