@@ -720,7 +720,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
720720 // do this after `check_and_deref_ptr` to ensure some basic sanity has already been checked.
721721 if !self . memory . validation_in_progress . get ( ) {
722722 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) ?;
724724 }
725725 }
726726
@@ -821,6 +821,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
821821 if let Some ( ( alloc_id, offset, prov, alloc, machine) ) = ptr_and_alloc {
822822 let range = alloc_range ( offset, size) ;
823823 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) ?;
824827 M :: before_memory_write (
825828 tcx,
826829 machine,
@@ -1396,6 +1399,14 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
13961399 let src_parts = self . get_ptr_access ( src, size) ?;
13971400 let dest_parts = self . get_ptr_access ( dest, size * num_copies) ?; // `Size` multiplication
13981401
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+
13991410 // FIXME: we look up both allocations twice here, once before for the `check_ptr_access`
14001411 // and once below to get the underlying `&[mut] Allocation`.
14011412
@@ -1408,12 +1419,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
14081419 let src_range = alloc_range ( src_offset, size) ;
14091420 assert ! ( !self . memory. validation_in_progress. get( ) , "we can't be copying during validation" ) ;
14101421
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
14131424 // 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- }
14171425 M :: before_memory_read (
14181426 tcx,
14191427 & self . machine ,
@@ -1438,16 +1446,18 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
14381446 let provenance = src_alloc
14391447 . provenance ( )
14401448 . 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 ) ) ?;
14421450 // Prepare a copy of the initialization mask.
14431451 let init = src_alloc. init_mask ( ) . prepare_copy ( src_range) ;
14441452
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) ?;
14471455 let dest_range = alloc_range ( dest_offset, size * num_copies) ;
1456+ // ...and access hooks.
1457+ M :: before_alloc_access ( tcx, machine, dest_alloc_id) ?;
14481458 M :: before_memory_write (
14491459 tcx,
1450- extra ,
1460+ machine ,
14511461 & mut dest_alloc. extra ,
14521462 dest,
14531463 ( dest_alloc_id, dest_prov) ,
0 commit comments