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).
This commit is contained in:
Matthias Krüger 2022-02-28 20:05:15 +01:00 committed by GitHub
commit 975a0e0141
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 35 additions and 7 deletions

View File

@ -453,7 +453,18 @@ pub fn codegen_place(
};
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())
}

View File

@ -1,6 +0,0 @@
// check-pass
#![feature(allocator_api)]
fn main() {
Box::new_in((), &std::alloc::Global);
}

View File

@ -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]));
}