@@ -720,7 +720,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
720
720
// do this after `check_and_deref_ptr` to ensure some basic sanity has already been checked.
721
721
if !self . memory . validation_in_progress . get ( ) {
722
722
if let Ok ( ( alloc_id, ..) ) = self . ptr_try_get_alloc_id ( ptr, size_i64) {
723
- M :: before_alloc_read ( self , alloc_id) ?;
723
+ M :: before_alloc_access ( self . tcx , & self . machine , alloc_id) ?;
724
724
}
725
725
}
726
726
@@ -821,6 +821,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
821
821
if let Some ( ( alloc_id, offset, prov, alloc, machine) ) = ptr_and_alloc {
822
822
let range = alloc_range ( offset, size) ;
823
823
if !validation_in_progress {
824
+ // For writes, it's okay to only call those when there actually is a non-zero
825
+ // amount of bytes to be written: a zero-sized write doesn't manifest anything.
826
+ M :: before_alloc_access ( tcx, machine, alloc_id) ?;
824
827
M :: before_memory_write (
825
828
tcx,
826
829
machine,
@@ -1396,6 +1399,14 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
1396
1399
let src_parts = self . get_ptr_access ( src, size) ?;
1397
1400
let dest_parts = self . get_ptr_access ( dest, size * num_copies) ?; // `Size` multiplication
1398
1401
1402
+ // Similar to `get_ptr_alloc`, we need to call `before_alloc_access` even for zero-sized
1403
+ // reads. However, just like in `get_ptr_alloc_mut`, the write part is okay to skip for
1404
+ // zero-sized writes.
1405
+ if let Ok ( ( alloc_id, ..) ) = self . ptr_try_get_alloc_id ( src, size. bytes ( ) . try_into ( ) . unwrap ( ) )
1406
+ {
1407
+ M :: before_alloc_access ( tcx, & self . machine , alloc_id) ?;
1408
+ }
1409
+
1399
1410
// FIXME: we look up both allocations twice here, once before for the `check_ptr_access`
1400
1411
// and once below to get the underlying `&[mut] Allocation`.
1401
1412
@@ -1408,12 +1419,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
1408
1419
let src_range = alloc_range ( src_offset, size) ;
1409
1420
assert ! ( !self . memory. validation_in_progress. get( ) , "we can't be copying during validation" ) ;
1410
1421
1411
- // Trigger read hooks .
1412
- // For the overlapping case, it is crucial that we trigger the read hooks
1422
+ // Trigger read hook .
1423
+ // For the overlapping case, it is crucial that we trigger the read hook
1413
1424
// before the write hook -- the aliasing model cares about the order.
1414
- if let Ok ( ( alloc_id, ..) ) = self . ptr_try_get_alloc_id ( src, size. bytes ( ) as i64 ) {
1415
- M :: before_alloc_read ( self , alloc_id) ?;
1416
- }
1417
1425
M :: before_memory_read (
1418
1426
tcx,
1419
1427
& self . machine ,
@@ -1438,16 +1446,18 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
1438
1446
let provenance = src_alloc
1439
1447
. provenance ( )
1440
1448
. prepare_copy ( src_range, dest_offset, num_copies, self )
1441
- . map_err ( |e| e. to_interp_error ( dest_alloc_id ) ) ?;
1449
+ . map_err ( |e| e. to_interp_error ( src_alloc_id ) ) ?;
1442
1450
// Prepare a copy of the initialization mask.
1443
1451
let init = src_alloc. init_mask ( ) . prepare_copy ( src_range) ;
1444
1452
1445
- // Destination alloc preparations and access hooks .
1446
- let ( dest_alloc, extra ) = self . get_alloc_raw_mut ( dest_alloc_id) ?;
1453
+ // Destination alloc preparations.. .
1454
+ let ( dest_alloc, machine ) = self . get_alloc_raw_mut ( dest_alloc_id) ?;
1447
1455
let dest_range = alloc_range ( dest_offset, size * num_copies) ;
1456
+ // ...and access hooks.
1457
+ M :: before_alloc_access ( tcx, machine, dest_alloc_id) ?;
1448
1458
M :: before_memory_write (
1449
1459
tcx,
1450
- extra ,
1460
+ machine ,
1451
1461
& mut dest_alloc. extra ,
1452
1462
dest,
1453
1463
( dest_alloc_id, dest_prov) ,
0 commit comments