diff options
| author | Ralf Jung <post@ralfj.de> | 2021-03-10 09:21:18 +0100 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2021-03-10 09:21:18 +0100 |
| commit | 9f27a13f5f620d1fcdc810b82033cee55804c3be (patch) | |
| tree | 4d41fb4a8952ce7fb32f051b37e14bebeefa6bd4 | |
| parent | 861872bc453bde79b83ff99d443d035225f10e87 (diff) | |
| download | rust-9f27a13f5f620d1fcdc810b82033cee55804c3be.tar.gz rust-9f27a13f5f620d1fcdc810b82033cee55804c3be.zip | |
fix copy_nonoverlapping
| -rw-r--r-- | compiler/rustc_mir/src/interpret/step.rs | 15 |
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)?; } |
