From bfa7d44823717c30bc21abc1ca3675d0b78c80a2 Mon Sep 17 00:00:00 2001 From: DrMeepster <19316085+DrMeepster@users.noreply.github.com> Date: Sun, 27 Feb 2022 00:48:17 -0800 Subject: [PATCH 1/2] fix box icing when it has aggregate abi --- compiler/rustc_codegen_ssa/src/mir/place.rs | 13 +++++++++++- src/test/ui/box/issue-81270-ice.rs | 22 +++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/box/issue-81270-ice.rs diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs index 6976999c0e4f7..aee385ab050e4 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 { .. }) + { + 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-81270-ice.rs b/src/test/ui/box/issue-81270-ice.rs new file mode 100644 index 0000000000000..fb42aed7aaebf --- /dev/null +++ b/src/test/ui/box/issue-81270-ice.rs @@ -0,0 +1,22 @@ +// check-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::alloc::AllocError> { + todo!() + } + unsafe fn deallocate(&self, _: std::ptr::NonNull, _: std::alloc::Layout) { + todo!() + } +} + +fn main() { + Box::new_in((), BigAllocator([0; 2])); +} From d316aba04c4644093ba07d1ec8d334b599b8eb01 Mon Sep 17 00:00:00 2001 From: DrMeepster <19316085+DrMeepster@users.noreply.github.com> Date: Sun, 27 Feb 2022 20:25:16 -0800 Subject: [PATCH 2/2] expadn abi check + condese & fix tests --- compiler/rustc_codegen_ssa/src/mir/place.rs | 2 +- src/test/ui/box/issue-78459-ice.rs | 6 ------ .../ui/box/{issue-81270-ice.rs => large-allocator-ice.rs} | 3 ++- 3 files changed, 3 insertions(+), 8 deletions(-) delete mode 100644 src/test/ui/box/issue-78459-ice.rs rename src/test/ui/box/{issue-81270-ice.rs => large-allocator-ice.rs} (88%) diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs index aee385ab050e4..809d64479084a 100644 --- a/compiler/rustc_codegen_ssa/src/mir/place.rs +++ b/compiler/rustc_codegen_ssa/src/mir/place.rs @@ -456,7 +456,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { 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 { .. }) + && matches!(cg_base.layout.abi, Abi::Aggregate { .. } | Abi::Uninhabited) { let ptr = cg_base.project_field(bx, 0).project_field(bx, 0); 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 89f75fea15b1d..0000000000000 --- 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/issue-81270-ice.rs b/src/test/ui/box/large-allocator-ice.rs similarity index 88% rename from src/test/ui/box/issue-81270-ice.rs rename to src/test/ui/box/large-allocator-ice.rs index fb42aed7aaebf..3ef1171ff50d9 100644 --- a/src/test/ui/box/issue-81270-ice.rs +++ b/src/test/ui/box/large-allocator-ice.rs @@ -1,4 +1,4 @@ -// check-pass +// build-pass #![feature(allocator_api)] use std::alloc::Allocator; @@ -18,5 +18,6 @@ unsafe impl Allocator for BigAllocator { } fn main() { + Box::new_in((), &std::alloc::Global); Box::new_in((), BigAllocator([0; 2])); }