@@ -15,9 +15,9 @@ use rustc_middle::ty::Ty;
15
15
use rustc_target:: abi:: { Abi , Align , FieldIdx , HasDataLayout , Size , FIRST_VARIANT } ;
16
16
17
17
use super :: {
18
- alloc_range, mir_assign_valid_types, AllocId , AllocRef , AllocRefMut , CheckInAllocMsg , ImmTy ,
19
- Immediate , InterpCx , InterpResult , Machine , MemoryKind , OpTy , Operand , Pointer ,
20
- PointerArithmetic , Projectable , Provenance , Readable , Scalar ,
18
+ alloc_range, mir_assign_valid_types, AllocId , AllocRef , AllocRefMut , ImmTy , Immediate ,
19
+ InterpCx , InterpResult , Machine , MemoryKind , OpTy , Operand , Pointer , PointerArithmetic ,
20
+ Projectable , Provenance , Readable , Scalar ,
21
21
} ;
22
22
23
23
#[ derive( Copy , Clone , Hash , PartialEq , Eq , Debug ) ]
@@ -88,17 +88,22 @@ impl<Prov: Provenance> MemPlace<Prov> {
88
88
89
89
#[ inline]
90
90
// Not called `offset_with_meta` to avoid confusion with the trait method.
91
- fn offset_with_meta_ < ' tcx > (
91
+ fn offset_with_meta_ < ' mir , ' tcx , M : Machine < ' mir , ' tcx , Provenance = Prov > > (
92
92
self ,
93
93
offset : Size ,
94
94
meta : MemPlaceMeta < Prov > ,
95
- cx : & impl HasDataLayout ,
95
+ ecx : & InterpCx < ' mir , ' tcx , M > ,
96
96
) -> InterpResult < ' tcx , Self > {
97
97
debug_assert ! (
98
98
!meta. has_meta( ) || self . meta. has_meta( ) ,
99
99
"cannot use `offset_with_meta` to add metadata to a place"
100
100
) ;
101
- Ok ( MemPlace { ptr : self . ptr . offset ( offset, cx) ?, meta } )
101
+ if offset > ecx. data_layout ( ) . max_size_of_val ( ) {
102
+ throw_ub ! ( PointerArithOverflow ) ;
103
+ }
104
+ let offset: i64 = offset. bytes ( ) . try_into ( ) . unwrap ( ) ;
105
+ let ptr = ecx. ptr_offset_inbounds ( self . ptr , offset) ?;
106
+ Ok ( MemPlace { ptr, meta } )
102
107
}
103
108
}
104
109
@@ -310,15 +315,18 @@ impl<'tcx, Prov: Provenance> Projectable<'tcx, Prov> for PlaceTy<'tcx, Prov> {
310
315
Right ( ( frame, local, old_offset) ) => {
311
316
debug_assert ! ( layout. is_sized( ) , "unsized locals should live in memory" ) ;
312
317
assert_matches ! ( meta, MemPlaceMeta :: None ) ; // we couldn't store it anyway...
313
- let new_offset = ecx
314
- . data_layout ( )
315
- . offset ( old_offset. unwrap_or ( Size :: ZERO ) . bytes ( ) , offset. bytes ( ) ) ?;
318
+ // `Place::Local` are always in-bounds of their surrounding local, so we can just
319
+ // check directly if this remains in-bounds. This cannot actually be violated since
320
+ // projections are type-checked and bounds-checked.
321
+ assert ! ( offset + layout. size <= self . layout. size) ;
322
+
323
+ let new_offset = Size :: from_bytes (
324
+ ecx. data_layout ( )
325
+ . offset ( old_offset. unwrap_or ( Size :: ZERO ) . bytes ( ) , offset. bytes ( ) ) ?,
326
+ ) ;
327
+
316
328
PlaceTy {
317
- place : Place :: Local {
318
- frame,
319
- local,
320
- offset : Some ( Size :: from_bytes ( new_offset) ) ,
321
- } ,
329
+ place : Place :: Local { frame, local, offset : Some ( new_offset) } ,
322
330
align : self . align . restrict_for_offset ( offset) ,
323
331
layout,
324
332
}
@@ -464,7 +472,6 @@ where
464
472
}
465
473
466
474
let mplace = self . ref_to_mplace ( & val) ?;
467
- self . check_mplace ( & mplace) ?;
468
475
Ok ( mplace)
469
476
}
470
477
@@ -494,17 +501,6 @@ where
494
501
self . get_ptr_alloc_mut ( mplace. ptr ( ) , size, mplace. align )
495
502
}
496
503
497
- /// Check if this mplace is dereferenceable and sufficiently aligned.
498
- pub fn check_mplace ( & self , mplace : & MPlaceTy < ' tcx , M :: Provenance > ) -> InterpResult < ' tcx > {
499
- let ( size, _align) = self
500
- . size_and_align_of_mplace ( & mplace) ?
501
- . unwrap_or ( ( mplace. layout . size , mplace. layout . align . abi ) ) ;
502
- // Due to packed places, only `mplace.align` matters.
503
- let align = if M :: enforce_alignment ( self ) { mplace. align } else { Align :: ONE } ;
504
- self . check_ptr_access_align ( mplace. ptr ( ) , size, align, CheckInAllocMsg :: DerefTest ) ?;
505
- Ok ( ( ) )
506
- }
507
-
508
504
/// Converts a repr(simd) place into a place where `place_index` accesses the SIMD elements.
509
505
/// Also returns the number of elements.
510
506
pub fn mplace_to_simd (
0 commit comments