@@ -158,8 +158,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
158
158
& self ,
159
159
ptr : Pointer < AllocId > ,
160
160
) -> InterpResult < ' tcx , Pointer < M :: PointerTag > > {
161
- // We know `offset` is relative to the allocation, so we can use `into_parts`.
162
- let ( alloc_id, offset) = ptr. into_parts ( ) ;
161
+ let alloc_id = ptr. provenance ;
163
162
// We need to handle `extern static`.
164
163
match self . tcx . get_global_alloc ( alloc_id) {
165
164
Some ( GlobalAlloc :: Static ( def_id) ) if self . tcx . is_thread_local_static ( def_id) => {
@@ -171,7 +170,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
171
170
_ => { }
172
171
}
173
172
// And we need to get the tag.
174
- Ok ( M :: tag_alloc_base_pointer ( self , Pointer :: new ( alloc_id , offset ) ) )
173
+ Ok ( M :: tag_alloc_base_pointer ( self , ptr ) )
175
174
}
176
175
177
176
pub fn create_fn_alloc_ptr (
@@ -238,7 +237,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
238
237
new_align : Align ,
239
238
kind : MemoryKind < M :: MemoryKind > ,
240
239
) -> InterpResult < ' tcx , Pointer < M :: PointerTag > > {
241
- let ( alloc_id, offset, ptr ) = self . ptr_get_alloc_id ( ptr) ?;
240
+ let ( alloc_id, offset, _tag ) = self . ptr_get_alloc_id ( ptr) ?;
242
241
if offset. bytes ( ) != 0 {
243
242
throw_ub_format ! (
244
243
"reallocating {:?} which does not point to the beginning of an object" ,
@@ -255,14 +254,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
255
254
} ;
256
255
// This will also call the access hooks.
257
256
self . mem_copy (
258
- ptr. into ( ) ,
257
+ ptr,
259
258
Align :: ONE ,
260
259
new_ptr. into ( ) ,
261
260
Align :: ONE ,
262
261
old_size. min ( new_size) ,
263
262
/*nonoverlapping*/ true ,
264
263
) ?;
265
- self . deallocate_ptr ( ptr. into ( ) , old_size_and_align, kind) ?;
264
+ self . deallocate_ptr ( ptr, old_size_and_align, kind) ?;
266
265
267
266
Ok ( new_ptr)
268
267
}
@@ -274,7 +273,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
274
273
old_size_and_align : Option < ( Size , Align ) > ,
275
274
kind : MemoryKind < M :: MemoryKind > ,
276
275
) -> InterpResult < ' tcx > {
277
- let ( alloc_id, offset, ptr ) = self . ptr_get_alloc_id ( ptr) ?;
276
+ let ( alloc_id, offset, tag ) = self . ptr_get_alloc_id ( ptr) ?;
278
277
trace ! ( "deallocating: {}" , alloc_id) ;
279
278
280
279
if offset. bytes ( ) != 0 {
@@ -330,7 +329,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
330
329
* self . tcx ,
331
330
& mut self . machine ,
332
331
& mut alloc. extra ,
333
- ptr . provenance ,
332
+ ( alloc_id , tag ) ,
334
333
alloc_range ( Size :: ZERO , size) ,
335
334
) ?;
336
335
@@ -350,17 +349,17 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
350
349
ptr : Pointer < Option < M :: PointerTag > > ,
351
350
size : Size ,
352
351
align : Align ,
353
- ) -> InterpResult < ' tcx , Option < ( AllocId , Size , Pointer < M :: PointerTag > ) > > {
352
+ ) -> InterpResult < ' tcx , Option < ( AllocId , Size , M :: TagExtra ) > > {
354
353
let align = M :: enforce_alignment ( & self ) . then_some ( align) ;
355
354
self . check_and_deref_ptr (
356
355
ptr,
357
356
size,
358
357
align,
359
358
CheckInAllocMsg :: MemoryAccessTest ,
360
- |alloc_id, offset, ptr | {
359
+ |alloc_id, offset, tag | {
361
360
let ( size, align) =
362
361
self . get_alloc_size_and_align ( alloc_id, AllocCheck :: Dereferenceable ) ?;
363
- Ok ( ( size, align, ( alloc_id, offset, ptr ) ) )
362
+ Ok ( ( size, align, ( alloc_id, offset, tag ) ) )
364
363
} ,
365
364
)
366
365
}
@@ -401,11 +400,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
401
400
size : Size ,
402
401
align : Option < Align > ,
403
402
msg : CheckInAllocMsg ,
404
- alloc_size : impl FnOnce (
405
- AllocId ,
406
- Size ,
407
- Pointer < M :: PointerTag > ,
408
- ) -> InterpResult < ' tcx , ( Size , Align , T ) > ,
403
+ alloc_size : impl FnOnce ( AllocId , Size , M :: TagExtra ) -> InterpResult < ' tcx , ( Size , Align , T ) > ,
409
404
) -> InterpResult < ' tcx , Option < T > > {
410
405
fn check_offset_align ( offset : u64 , align : Align ) -> InterpResult < ' static > {
411
406
if offset % align. bytes ( ) == 0 {
@@ -433,8 +428,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
433
428
}
434
429
None
435
430
}
436
- Ok ( ( alloc_id, offset, ptr ) ) => {
437
- let ( alloc_size, alloc_align, ret_val) = alloc_size ( alloc_id, offset, ptr ) ?;
431
+ Ok ( ( alloc_id, offset, tag ) ) => {
432
+ let ( alloc_size, alloc_align, ret_val) = alloc_size ( alloc_id, offset, tag ) ?;
438
433
// Test bounds. This also ensures non-null.
439
434
// It is sufficient to check this for the end pointer. Also check for overflow!
440
435
if offset. checked_add ( size, & self . tcx ) . map_or ( true , |end| end > alloc_size) {
@@ -450,10 +445,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
450
445
// we want the error to be about the bounds.
451
446
if let Some ( align) = align {
452
447
if M :: force_int_for_alignment_check ( self ) {
453
- let addr = Scalar :: from_pointer ( ptr, & self . tcx )
454
- . to_machine_usize ( & self . tcx )
455
- . expect ( "ptr-to-int cast for align check should never fail" ) ;
456
- check_offset_align ( addr, align) ?;
448
+ // `force_int_for_alignment_check` can only be true if `OFFSET_IS_ADDR` is true.
449
+ check_offset_align ( ptr. addr ( ) . bytes ( ) , align) ?;
457
450
} else {
458
451
// Check allocation alignment and offset alignment.
459
452
if alloc_align. bytes ( ) < align. bytes ( ) {
@@ -569,14 +562,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
569
562
size,
570
563
align,
571
564
CheckInAllocMsg :: MemoryAccessTest ,
572
- |alloc_id, offset, ptr | {
565
+ |alloc_id, offset, tag | {
573
566
let alloc = self . get_alloc_raw ( alloc_id) ?;
574
- Ok ( ( alloc. size ( ) , alloc. align , ( alloc_id, offset, ptr , alloc) ) )
567
+ Ok ( ( alloc. size ( ) , alloc. align , ( alloc_id, offset, tag , alloc) ) )
575
568
} ,
576
569
) ?;
577
- if let Some ( ( alloc_id, offset, ptr , alloc) ) = ptr_and_alloc {
570
+ if let Some ( ( alloc_id, offset, tag , alloc) ) = ptr_and_alloc {
578
571
let range = alloc_range ( offset, size) ;
579
- M :: memory_read ( * self . tcx , & self . machine , & alloc. extra , ptr . provenance , range) ?;
572
+ M :: memory_read ( * self . tcx , & self . machine , & alloc. extra , ( alloc_id , tag ) , range) ?;
580
573
Ok ( Some ( AllocRef { alloc, range, tcx : * self . tcx , alloc_id } ) )
581
574
} else {
582
575
// Even in this branch we have to be sure that we actually access the allocation, in
@@ -631,13 +624,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
631
624
align : Align ,
632
625
) -> InterpResult < ' tcx , Option < AllocRefMut < ' a , ' tcx , M :: PointerTag , M :: AllocExtra > > > {
633
626
let parts = self . get_ptr_access ( ptr, size, align) ?;
634
- if let Some ( ( alloc_id, offset, ptr ) ) = parts {
627
+ if let Some ( ( alloc_id, offset, tag ) ) = parts {
635
628
let tcx = * self . tcx ;
636
629
// FIXME: can we somehow avoid looking up the allocation twice here?
637
630
// We cannot call `get_raw_mut` inside `check_and_deref_ptr` as that would duplicate `&mut self`.
638
631
let ( alloc, machine) = self . get_alloc_raw_mut ( alloc_id) ?;
639
632
let range = alloc_range ( offset, size) ;
640
- M :: memory_written ( tcx, machine, & mut alloc. extra , ptr . provenance , range) ?;
633
+ M :: memory_written ( tcx, machine, & mut alloc. extra , ( alloc_id , tag ) , range) ?;
641
634
Ok ( Some ( AllocRefMut { alloc, range, tcx, alloc_id } ) )
642
635
} else {
643
636
Ok ( None )
@@ -732,7 +725,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
732
725
ptr : Pointer < Option < M :: PointerTag > > ,
733
726
) -> InterpResult < ' tcx , FnVal < ' tcx , M :: ExtraFnVal > > {
734
727
trace ! ( "get_fn({:?})" , ptr) ;
735
- let ( alloc_id, offset, _ptr ) = self . ptr_get_alloc_id ( ptr) ?;
728
+ let ( alloc_id, offset, _tag ) = self . ptr_get_alloc_id ( ptr) ?;
736
729
if offset. bytes ( ) != 0 {
737
730
throw_ub ! ( InvalidFunctionPointer ( Pointer :: new( alloc_id, offset) ) )
738
731
}
@@ -1012,16 +1005,16 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
1012
1005
// and once below to get the underlying `&[mut] Allocation`.
1013
1006
1014
1007
// Source alloc preparations and access hooks.
1015
- let Some ( ( src_alloc_id, src_offset, src ) ) = src_parts else {
1008
+ let Some ( ( src_alloc_id, src_offset, src_tag ) ) = src_parts else {
1016
1009
// Zero-sized *source*, that means dst is also zero-sized and we have nothing to do.
1017
1010
return Ok ( ( ) ) ;
1018
1011
} ;
1019
1012
let src_alloc = self . get_alloc_raw ( src_alloc_id) ?;
1020
1013
let src_range = alloc_range ( src_offset, size) ;
1021
- M :: memory_read ( * tcx, & self . machine , & src_alloc. extra , src . provenance , src_range) ?;
1014
+ M :: memory_read ( * tcx, & self . machine , & src_alloc. extra , ( src_alloc_id , src_tag ) , src_range) ?;
1022
1015
// We need the `dest` ptr for the next operation, so we get it now.
1023
1016
// We already did the source checks and called the hooks so we are good to return early.
1024
- let Some ( ( dest_alloc_id, dest_offset, dest ) ) = dest_parts else {
1017
+ let Some ( ( dest_alloc_id, dest_offset, dest_tag ) ) = dest_parts else {
1025
1018
// Zero-sized *destination*.
1026
1019
return Ok ( ( ) ) ;
1027
1020
} ;
@@ -1043,7 +1036,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
1043
1036
// Destination alloc preparations and access hooks.
1044
1037
let ( dest_alloc, extra) = self . get_alloc_raw_mut ( dest_alloc_id) ?;
1045
1038
let dest_range = alloc_range ( dest_offset, size * num_copies) ;
1046
- M :: memory_written ( * tcx, extra, & mut dest_alloc. extra , dest. provenance , dest_range) ?;
1039
+ M :: memory_written (
1040
+ * tcx,
1041
+ extra,
1042
+ & mut dest_alloc. extra ,
1043
+ ( dest_alloc_id, dest_tag) ,
1044
+ dest_range,
1045
+ ) ?;
1047
1046
let dest_bytes = dest_alloc
1048
1047
. get_bytes_mut_ptr ( & tcx, dest_range)
1049
1048
. map_err ( |e| e. to_interp_error ( dest_alloc_id) ) ?
@@ -1164,11 +1163,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
1164
1163
pub fn ptr_try_get_alloc_id (
1165
1164
& self ,
1166
1165
ptr : Pointer < Option < M :: PointerTag > > ,
1167
- ) -> Result < ( AllocId , Size , Pointer < M :: PointerTag > ) , u64 > {
1166
+ ) -> Result < ( AllocId , Size , M :: TagExtra ) , u64 > {
1168
1167
match ptr. into_pointer_or_addr ( ) {
1169
1168
Ok ( ptr) => {
1170
- let ( alloc_id, offset) = M :: ptr_get_alloc ( self , ptr) ;
1171
- Ok ( ( alloc_id, offset, ptr ) )
1169
+ let ( alloc_id, offset, extra ) = M :: ptr_get_alloc ( self , ptr) ;
1170
+ Ok ( ( alloc_id, offset, extra ) )
1172
1171
}
1173
1172
Err ( addr) => Err ( addr. bytes ( ) ) ,
1174
1173
}
@@ -1179,7 +1178,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
1179
1178
pub fn ptr_get_alloc_id (
1180
1179
& self ,
1181
1180
ptr : Pointer < Option < M :: PointerTag > > ,
1182
- ) -> InterpResult < ' tcx , ( AllocId , Size , Pointer < M :: PointerTag > ) > {
1181
+ ) -> InterpResult < ' tcx , ( AllocId , Size , M :: TagExtra ) > {
1183
1182
self . ptr_try_get_alloc_id ( ptr) . map_err ( |offset| {
1184
1183
err_ub ! ( DanglingIntPointer ( offset, CheckInAllocMsg :: InboundsTest ) ) . into ( )
1185
1184
} )
0 commit comments