@@ -115,11 +115,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
115
115
}
116
116
117
117
// Call CopyNonOverlapping
118
- CopyNonOverlapping ( box rustc_middle:: mir:: CopyNonOverlapping { dst, src, count } ) => {
119
- let count = self . eval_operand ( count, None ) ?;
120
-
118
+ CopyNonOverlapping ( box rustc_middle:: mir:: CopyNonOverlapping { src, dst, count } ) => {
121
119
let src = self . eval_operand ( src, None ) ?;
122
120
let dst = self . eval_operand ( dst, None ) ?;
121
+ let count = self . eval_operand ( count, None ) ?;
123
122
self . copy ( & src, & dst, & count, /* nonoverlapping */ true ) ?;
124
123
}
125
124
@@ -160,16 +159,18 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
160
159
let count = self . read_scalar ( & count) ?. to_machine_usize ( self ) ?;
161
160
let layout = self . layout_of ( src. layout . ty . builtin_deref ( true ) . unwrap ( ) . ty ) ?;
162
161
let ( size, align) = ( layout. size , layout. align . abi ) ;
162
+ let size = size. checked_mul ( count, self ) . ok_or_else ( || {
163
+ err_ub_format ! ( "overflow computing total size of `copy_nonoverlapping`" )
164
+ } ) ?;
165
+
166
+ // Make sure we check both pointers for an access of the total size and aligment,
167
+ // *even if* the total size is 0.
163
168
let src =
164
169
self . memory . check_ptr_access ( self . read_scalar ( & src) ?. check_init ( ) ?, size, align) ?;
165
170
166
171
let dst =
167
172
self . memory . check_ptr_access ( self . read_scalar ( & dst) ?. check_init ( ) ?, size, align) ?;
168
173
169
- let size = size. checked_mul ( count, self ) . ok_or_else ( || {
170
- err_ub_format ! ( "overflow computing total size of `copy_nonoverlapping`" )
171
- } ) ?;
172
-
173
174
if let ( Some ( src) , Some ( dst) ) = ( src, dst) {
174
175
self . memory . copy ( src, dst, size, nonoverlapping) ?;
175
176
}
0 commit comments