Skip to content

Commit

Permalink
Rollup merge of #95328 - DrMeepster:box_gep_err, r=oli-obk
Browse files Browse the repository at this point in the history
Fix yet another Box<T, A> ICE

Fixes #95036.

This widens the special case from #94414 to make sure that boxes with a custom allocator are never directly dereferenced.
  • Loading branch information
Dylan-DPC authored Mar 28, 2022
2 parents e10d503 + 09ccc63 commit ce319ac
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 7 deletions.
20 changes: 13 additions & 7 deletions compiler/rustc_codegen_ssa/src/mir/place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -441,11 +441,19 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
.find(|elem| matches!(elem.1, mir::ProjectionElem::Deref))
{
base = elem.0 + 1;
self.codegen_consume(
let cg_base = self.codegen_consume(
bx,
mir::PlaceRef { projection: &place_ref.projection[..elem.0], ..place_ref },
)
.deref(bx.cx())
);

// a box with a non-zst allocator should not be directly dereferenced
if cg_base.layout.ty.is_box() && !cg_base.layout.field(cx, 1).is_zst() {
let ptr = cg_base.extract_field(bx, 0).extract_field(bx, 0);

ptr.deref(bx.cx())
} else {
cg_base.deref(bx.cx())
}
} else {
bug!("using operand local {:?} as place", place_ref);
}
Expand All @@ -454,10 +462,8 @@ 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 => {
// 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)
{
// a box with a non-zst allocator should not be directly dereferenced
if cg_base.layout.ty.is_box() && !cg_base.layout.field(cx, 1).is_zst() {
let ptr = cg_base.project_field(bx, 0).project_field(bx, 0);

bx.load_operand(ptr).deref(bx.cx())
Expand Down
22 changes: 22 additions & 0 deletions src/test/ui/box/issue-95036.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// compile-flags: -O
// build-pass

#![feature(allocator_api, bench_black_box)]

#[inline(never)]
pub fn by_ref(node: &mut Box<[u8; 1], &std::alloc::Global>) {
node[0] = 9u8;
}

pub fn main() {
let mut node = Box::new_in([5u8], &std::alloc::Global);
node[0] = 7u8;

std::hint::black_box(node);

let mut node = Box::new_in([5u8], &std::alloc::Global);

by_ref(&mut node);

std::hint::black_box(node);
}

0 comments on commit ce319ac

Please sign in to comment.