From 4ad53dc9f5b43e0fa27622e3e40faeac15f00f31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Sun, 20 Dec 2020 00:00:00 +0000 Subject: [PATCH] Use pointer type in AtomicPtr::swap implementation --- compiler/rustc_codegen_ssa/src/mir/intrinsic.rs | 15 +++++++++++++-- library/core/src/sync/atomic.rs | 10 +++++++++- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index 34022643101..80e3ed75b85 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -524,8 +524,19 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { }; let ty = substs.type_at(0); - if int_type_width_signed(ty, bx.tcx()).is_some() { - bx.atomic_rmw(atom_op, args[0].immediate(), args[1].immediate(), order) + if int_type_width_signed(ty, bx.tcx()).is_some() + || (ty.is_unsafe_ptr() && op == "xchg") + { + let mut ptr = args[0].immediate(); + let mut val = args[1].immediate(); + if ty.is_unsafe_ptr() { + // Some platforms do not support atomic operations on pointers, + // so we cast to integer first. + let ptr_llty = bx.type_ptr_to(bx.type_isize()); + ptr = bx.pointercast(ptr, ptr_llty); + val = bx.ptrtoint(val, bx.type_isize()); + } + bx.atomic_rmw(atom_op, ptr, val, order) } else { return invalid_monomorphization(ty); } diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index be6c86b5176..a96da9aa6dc 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -1040,8 +1040,16 @@ impl AtomicPtr { #[stable(feature = "rust1", since = "1.0.0")] #[cfg(target_has_atomic = "ptr")] pub fn swap(&self, ptr: *mut T, order: Ordering) -> *mut T { + #[cfg(bootstrap)] // SAFETY: data races are prevented by atomic intrinsics. - unsafe { atomic_swap(self.p.get() as *mut usize, ptr as usize, order) as *mut T } + unsafe { + atomic_swap(self.p.get() as *mut usize, ptr as usize, order) as *mut T + } + #[cfg(not(bootstrap))] + // SAFETY: data races are prevented by atomic intrinsics. + unsafe { + atomic_swap(self.p.get(), ptr, order) + } } /// Stores a value into the pointer if the current value is the same as the `current` value.