@@ -115,11 +115,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
115115 }
116116
117117 // 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 } ) => {
121119 let src = self . eval_operand ( src, None ) ?;
122120 let dst = self . eval_operand ( dst, None ) ?;
121+ let count = self . eval_operand ( count, None ) ?;
123122 self . copy ( & src, & dst, & count, /* nonoverlapping */ true ) ?;
124123 }
125124
@@ -160,16 +159,18 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
160159 let count = self . read_scalar ( & count) ?. to_machine_usize ( self ) ?;
161160 let layout = self . layout_of ( src. layout . ty . builtin_deref ( true ) . unwrap ( ) . ty ) ?;
162161 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.
163168 let src =
164169 self . memory . check_ptr_access ( self . read_scalar ( & src) ?. check_init ( ) ?, size, align) ?;
165170
166171 let dst =
167172 self . memory . check_ptr_access ( self . read_scalar ( & dst) ?. check_init ( ) ?, size, align) ?;
168173
169- let size = size. checked_mul ( count, self ) . ok_or_else ( || {
170- err_ub_format ! ( "overflow computing total size of `copy_nonoverlapping`" )
171- } ) ?;
172-
173174 if let ( Some ( src) , Some ( dst) ) = ( src, dst) {
174175 self . memory . copy ( src, dst, size, nonoverlapping) ?;
175176 }
0 commit comments