about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorDylan DPC <dylan.dpc@gmail.com>2020-04-23 20:35:04 +0200
committerGitHub <noreply@github.com>2020-04-23 20:35:04 +0200
commit199f4deef0ac8ccfe02a8290eadd0ab3ae66d71c (patch)
tree2aff5b15c1c8cdeb21c21d052d9a4cac3bd834d3 /src
parent1363a4b3522feccdba4e4fc19cacb80f50e26e9a (diff)
parent99de3728f95d1a3fa6063aa4ef2974a45cf35f4c (diff)
downloadrust-199f4deef0ac8ccfe02a8290eadd0ab3ae66d71c.tar.gz
rust-199f4deef0ac8ccfe02a8290eadd0ab3ae66d71c.zip
Rollup merge of #71446 - Amanieu:transmute_copy, r=sfackler
Only use read_unaligned in transmute_copy if necessary

I've noticed that this causes LLVM to generate poor code on targets that don't support unaligned memory accesses.
Diffstat (limited to 'src')
-rw-r--r--src/libcore/mem/mod.rs7
1 files changed, 6 insertions, 1 deletions
diff --git a/src/libcore/mem/mod.rs b/src/libcore/mem/mod.rs
index 3fa2b7a2d04..7fcfbf10814 100644
--- a/src/libcore/mem/mod.rs
+++ b/src/libcore/mem/mod.rs
@@ -924,7 +924,12 @@ pub fn drop<T>(_x: T) {}
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
-    ptr::read_unaligned(src as *const T as *const U)
+    // If U has a higher alignment requirement, src may not be suitably aligned.
+    if align_of::<U>() > align_of::<T>() {
+        ptr::read_unaligned(src as *const T as *const U)
+    } else {
+        ptr::read(src as *const T as *const U)
+    }
 }
 
 /// Opaque type representing the discriminant of an enum.