@@ -1096,23 +1096,18 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
1096
1096
// The pointers above remain valid even if the `HashMap` table is moved around because they
1097
1097
// point into the `Vec` storing the bytes.
1098
1098
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 ) {
1100
1100
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
+ ) ;
1106
1109
}
1107
1110
}
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
- }
1116
1111
} else {
1117
1112
for i in 0 ..num_copies {
1118
1113
ptr:: copy_nonoverlapping (
@@ -1211,4 +1206,18 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
1211
1206
err_ub ! ( DanglingIntPointer ( offset, CheckInAllocMsg :: InboundsTest ) ) . into ( )
1212
1207
} )
1213
1208
}
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
+ }
1214
1223
}
0 commit comments