Skip to content

Commit 1b77f8e

Browse files
committed
Constify intrinsics::copy[_nonoverlapping]
1 parent 463ce40 commit 1b77f8e

File tree

2 files changed

+34
-6
lines changed

2 files changed

+34
-6
lines changed

compiler/rustc_mir/src/interpret/intrinsics.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,29 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
322322
let result = Scalar::from_uint(truncated_bits, layout.size);
323323
self.write_scalar(result, dest)?;
324324
}
325+
sym::copy | sym::copy_nonoverlapping => {
326+
let elem_ty = instance.substs.type_at(0);
327+
let elem_layout = self.layout_of(elem_ty)?;
328+
let count = self.read_scalar(args[2])?.to_machine_usize(self)?;
329+
let elem_align = elem_layout.align.abi;
330+
331+
let size = elem_layout.size.checked_mul(count, self).ok_or_else(|| {
332+
err_ub_format!("overflow computing total size of `{}`", intrinsic_name)
333+
})?;
334+
let src = self.read_scalar(args[0])?.check_init()?;
335+
let src = self.memory.check_ptr_access(src, size, elem_align)?;
336+
let dest = self.read_scalar(args[1])?.check_init()?;
337+
let dest = self.memory.check_ptr_access(dest, size, elem_align)?;
338+
339+
if let (Some(src), Some(dest)) = (src, dest) {
340+
self.memory.copy(
341+
src,
342+
dest,
343+
size,
344+
intrinsic_name == sym::copy_nonoverlapping,
345+
)?;
346+
}
347+
}
325348
sym::offset => {
326349
let ptr = self.read_scalar(args[0])?.check_init()?;
327350
let offset_count = self.read_scalar(args[1])?.to_machine_isize(self)?;

library/core/src/intrinsics.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1846,20 +1846,22 @@ pub(crate) fn is_nonoverlapping<T>(src: *const T, dst: *const T, count: usize) -
18461846
/// [`Vec::append`]: ../../std/vec/struct.Vec.html#method.append
18471847
#[doc(alias = "memcpy")]
18481848
#[stable(feature = "rust1", since = "1.0.0")]
1849+
#[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "none")]
18491850
#[inline]
1850-
pub unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize) {
1851+
pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize) {
18511852
extern "rust-intrinsic" {
18521853
fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
18531854
}
18541855

1855-
if cfg!(debug_assertions)
1856+
// FIXME: Perform these checks only at run time
1857+
/*if cfg!(debug_assertions)
18561858
&& !(is_aligned_and_not_null(src)
18571859
&& is_aligned_and_not_null(dst)
18581860
&& is_nonoverlapping(src, dst, count))
18591861
{
18601862
// Not panicking to keep codegen impact smaller.
18611863
abort();
1862-
}
1864+
}*/
18631865

18641866
// SAFETY: the safety contract for `copy_nonoverlapping` must be
18651867
// upheld by the caller.
@@ -1928,16 +1930,19 @@ pub unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize) {
19281930
/// ```
19291931
#[doc(alias = "memmove")]
19301932
#[stable(feature = "rust1", since = "1.0.0")]
1933+
#[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "none")]
19311934
#[inline]
1932-
pub unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
1935+
pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
19331936
extern "rust-intrinsic" {
1937+
#[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "none")]
19341938
fn copy<T>(src: *const T, dst: *mut T, count: usize);
19351939
}
19361940

1937-
if cfg!(debug_assertions) && !(is_aligned_and_not_null(src) && is_aligned_and_not_null(dst)) {
1941+
// FIXME: Perform these checks only at run time
1942+
/*if cfg!(debug_assertions) && !(is_aligned_and_not_null(src) && is_aligned_and_not_null(dst)) {
19381943
// Not panicking to keep codegen impact smaller.
19391944
abort();
1940-
}
1945+
}*/
19411946

19421947
// SAFETY: the safety contract for `copy` must be upheld by the caller.
19431948
unsafe { copy(src, dst, count) }

0 commit comments

Comments
 (0)