about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2022-02-28 20:05:15 +0100
committerGitHub <noreply@github.com>2022-02-28 20:05:15 +0100
commit975a0e0141c94a09cf4cba4499ce981da643d07e (patch)
tree5d40487dd9e61409c6077c76191bc9d082b71378
parent934079180da6e75ee2398d0342857797df5c7a49 (diff)
parentd316aba04c4644093ba07d1ec8d334b599b8eb01 (diff)
downloadrust-975a0e0141c94a09cf4cba4499ce981da643d07e.tar.gz
rust-975a0e0141c94a09cf4cba4499ce981da643d07e.zip
Rollup merge of #94414 - DrMeepster:box_alloc_ice2, r=tmiasko
Fix ICE when using Box<T, A> with large A

A sequel to #94043 that fixes #81270 and #92054 (duplicate).
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/place.rs13
-rw-r--r--src/test/ui/box/issue-78459-ice.rs6
-rw-r--r--src/test/ui/box/large-allocator-ice.rs23
3 files changed, 35 insertions, 7 deletions
diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs
index 6976999c0e4..809d6447908 100644
--- a/compiler/rustc_codegen_ssa/src/mir/place.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/place.rs
@@ -453,7 +453,18 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         };
         for elem in place_ref.projection[base..].iter() {
             cg_base = match elem.clone() {
-                mir::ProjectionElem::Deref => bx.load_operand(cg_base).deref(bx.cx()),
+                mir::ProjectionElem::Deref => {
+                    // custom allocators can change box's abi, making it unable to be derefed directly
+                    if cg_base.layout.ty.is_box()
+                        && matches!(cg_base.layout.abi, Abi::Aggregate { .. } | Abi::Uninhabited)
+                    {
+                        let ptr = cg_base.project_field(bx, 0).project_field(bx, 0);
+
+                        bx.load_operand(ptr).deref(bx.cx())
+                    } else {
+                        bx.load_operand(cg_base).deref(bx.cx())
+                    }
+                }
                 mir::ProjectionElem::Field(ref field, _) => {
                     cg_base.project_field(bx, field.index())
                 }
diff --git a/src/test/ui/box/issue-78459-ice.rs b/src/test/ui/box/issue-78459-ice.rs
deleted file mode 100644
index 89f75fea15b..00000000000
--- a/src/test/ui/box/issue-78459-ice.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-// check-pass
-#![feature(allocator_api)]
-
-fn main() {
-    Box::new_in((), &std::alloc::Global);
-}
diff --git a/src/test/ui/box/large-allocator-ice.rs b/src/test/ui/box/large-allocator-ice.rs
new file mode 100644
index 00000000000..3ef1171ff50
--- /dev/null
+++ b/src/test/ui/box/large-allocator-ice.rs
@@ -0,0 +1,23 @@
+// build-pass
+#![feature(allocator_api)]
+
+use std::alloc::Allocator;
+
+struct BigAllocator([usize; 2]);
+
+unsafe impl Allocator for BigAllocator {
+    fn allocate(
+        &self,
+        _: std::alloc::Layout,
+    ) -> Result<std::ptr::NonNull<[u8]>, std::alloc::AllocError> {
+        todo!()
+    }
+    unsafe fn deallocate(&self, _: std::ptr::NonNull<u8>, _: std::alloc::Layout) {
+        todo!()
+    }
+}
+
+fn main() {
+    Box::new_in((), &std::alloc::Global);
+    Box::new_in((), BigAllocator([0; 2]));
+}