@@ -1096,23 +1096,18 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
10961096 // The pointers above remain valid even if the `HashMap` table is moved around because they
10971097 // point into the `Vec` storing the bytes.
10981098 unsafe {
1099- if src_alloc_id == dest_alloc_id {
1099+ if Self :: check_ptr_overlap ( src_alloc_id, src_offset , dest_alloc_id, dest_offset , size ) {
11001100 if nonoverlapping {
1101- // `Size` additions
1102- if ( src_offset <= dest_offset && src_offset + size > dest_offset)
1103- || ( dest_offset <= src_offset && dest_offset + size > src_offset)
1104- {
1105- throw_ub_format ! ( "copy_nonoverlapping called on overlapping ranges" )
1101+ throw_ub_format ! ( "copy_nonoverlapping called on overlapping ranges" )
1102+ } else {
1103+ for i in 0 ..num_copies {
1104+ ptr:: copy (
1105+ src_bytes,
1106+ dest_bytes. add ( ( size * i) . bytes_usize ( ) ) , // `Size` multiplication
1107+ size. bytes_usize ( ) ,
1108+ ) ;
11061109 }
11071110 }
1108-
1109- for i in 0 ..num_copies {
1110- ptr:: copy (
1111- src_bytes,
1112- dest_bytes. add ( ( size * i) . bytes_usize ( ) ) , // `Size` multiplication
1113- size. bytes_usize ( ) ,
1114- ) ;
1115- }
11161111 } else {
11171112 for i in 0 ..num_copies {
11181113 ptr:: copy_nonoverlapping (
@@ -1211,4 +1206,18 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
12111206 err_ub ! ( DanglingIntPointer ( offset, CheckInAllocMsg :: InboundsTest ) ) . into ( )
12121207 } )
12131208 }
1209+
1210+ /// Check if a `src` ptr overlaps with a `dest` ptr.
1211+ #[ inline( always) ]
1212+ pub fn check_ptr_overlap (
1213+ src_id : AllocId ,
1214+ src_offset : Size ,
1215+ dest_id : AllocId ,
1216+ dest_offset : Size ,
1217+ size : Size ,
1218+ ) -> bool {
1219+ let overlaps = |a, b| a <= b && b < a + size;
1220+ src_id == dest_id
1221+ && ( overlaps ( src_offset, dest_offset) || overlaps ( dest_offset, src_offset) )
1222+ }
12141223}
0 commit comments