@@ -1159,11 +1159,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
1159
1159
} ;
1160
1160
1161
1161
// Side-step AllocRef and directly access the underlying bytes more efficiently.
1162
- // (We are staying inside the bounds here so all is good.)
1162
+ // (We are staying inside the bounds here and all bytes do get overwritten so all is good.)
1163
1163
let alloc_id = alloc_ref. alloc_id ;
1164
1164
let bytes = alloc_ref
1165
1165
. alloc
1166
- . get_bytes_mut ( & alloc_ref. tcx , alloc_ref. range )
1166
+ . get_bytes_unchecked_for_overwrite ( & alloc_ref. tcx , alloc_ref. range )
1167
1167
. map_err ( move |e| e. to_interp_error ( alloc_id) ) ?;
1168
1168
// `zip` would stop when the first iterator ends; we want to definitely
1169
1169
// cover all of `bytes`.
@@ -1184,6 +1184,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
1184
1184
self . mem_copy_repeatedly ( src, dest, size, 1 , nonoverlapping)
1185
1185
}
1186
1186
1187
+ /// Performs `num_copies` many copies of `size` many bytes from `src` to `dest + i*size` (where
1188
+ /// `i` is the index of the copy).
1189
+ ///
1190
+ /// Either `nonoverlapping` must be true or `num_copies` must be 1; doing repeated copies that
1191
+ /// may overlap is not supported.
1187
1192
pub fn mem_copy_repeatedly (
1188
1193
& mut self ,
1189
1194
src : Pointer < Option < M :: Provenance > > ,
@@ -1245,8 +1250,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
1245
1250
( dest_alloc_id, dest_prov) ,
1246
1251
dest_range,
1247
1252
) ?;
1253
+ // Yes we do overwrite all bytes in `dest_bytes`.
1248
1254
let dest_bytes = dest_alloc
1249
- . get_bytes_mut_ptr ( & tcx, dest_range)
1255
+ . get_bytes_unchecked_for_overwrite_ptr ( & tcx, dest_range)
1250
1256
. map_err ( |e| e. to_interp_error ( dest_alloc_id) ) ?
1251
1257
. as_mut_ptr ( ) ;
1252
1258
@@ -1280,6 +1286,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
1280
1286
}
1281
1287
}
1282
1288
}
1289
+ if num_copies > 1 {
1290
+ assert ! ( nonoverlapping, "multi-copy only supported in non-overlapping mode" ) ;
1291
+ }
1283
1292
1284
1293
let size_in_bytes = size. bytes_usize ( ) ;
1285
1294
// For particularly large arrays (where this is perf-sensitive) it's common that
@@ -1292,6 +1301,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
1292
1301
} else if src_alloc_id == dest_alloc_id {
1293
1302
let mut dest_ptr = dest_bytes;
1294
1303
for _ in 0 ..num_copies {
1304
+ // Here we rely on `src` and `dest` being non-overlapping if there is more than
1305
+ // one copy.
1295
1306
ptr:: copy ( src_bytes, dest_ptr, size_in_bytes) ;
1296
1307
dest_ptr = dest_ptr. add ( size_in_bytes) ;
1297
1308
}
0 commit comments