about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2021-03-10 09:21:18 +0100
committerRalf Jung <post@ralfj.de>2021-03-10 09:21:18 +0100
commit9f27a13f5f620d1fcdc810b82033cee55804c3be (patch)
tree4d41fb4a8952ce7fb32f051b37e14bebeefa6bd4
parent861872bc453bde79b83ff99d443d035225f10e87 (diff)
downloadrust-9f27a13f5f620d1fcdc810b82033cee55804c3be.tar.gz
rust-9f27a13f5f620d1fcdc810b82033cee55804c3be.zip
fix copy_nonoverlapping
-rw-r--r--compiler/rustc_mir/src/interpret/step.rs15
1 files changed, 8 insertions, 7 deletions
diff --git a/compiler/rustc_mir/src/interpret/step.rs b/compiler/rustc_mir/src/interpret/step.rs
index 0f365eaa41d..2bed3b2c3ad 100644
--- a/compiler/rustc_mir/src/interpret/step.rs
+++ b/compiler/rustc_mir/src/interpret/step.rs
@@ -115,11 +115,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             }
 
             // Call CopyNonOverlapping
-            CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping { dst, src, count }) => {
-                let count = self.eval_operand(count, None)?;
-
+            CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping { src, dst, count }) => {
                 let src = self.eval_operand(src, None)?;
                 let dst = self.eval_operand(dst, None)?;
+                let count = self.eval_operand(count, None)?;
                 self.copy(&src, &dst, &count, /* nonoverlapping */ true)?;
             }
 
@@ -160,16 +159,18 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         let count = self.read_scalar(&count)?.to_machine_usize(self)?;
         let layout = self.layout_of(src.layout.ty.builtin_deref(true).unwrap().ty)?;
         let (size, align) = (layout.size, layout.align.abi);
+        let size = size.checked_mul(count, self).ok_or_else(|| {
+            err_ub_format!("overflow computing total size of `copy_nonoverlapping`")
+        })?;
+
+        // Make sure we check both pointers for an access of the total size and aligment,
+        // *even if* the total size is 0.
         let src =
             self.memory.check_ptr_access(self.read_scalar(&src)?.check_init()?, size, align)?;
 
         let dst =
             self.memory.check_ptr_access(self.read_scalar(&dst)?.check_init()?, size, align)?;
 
-        let size = size.checked_mul(count, self).ok_or_else(|| {
-            err_ub_format!("overflow computing total size of `copy_nonoverlapping`")
-        })?;
-
         if let (Some(src), Some(dst)) = (src, dst) {
             self.memory.copy(src, dst, size, nonoverlapping)?;
         }