Skip to content

Commit ce319ac

Browse files
authoredMar 28, 2022
Rollup merge of rust-lang#95328 - DrMeepster:box_gep_err, r=oli-obk
Fix yet another Box<T, A> ICE Fixes rust-lang#95036. This widens the special case from rust-lang#94414 to make sure that boxes with a custom allocator are never directly dereferenced.
2 parents e10d503 + 09ccc63 commit ce319ac

File tree

2 files changed

+35
-7
lines changed

2 files changed

+35
-7
lines changed
 

‎compiler/rustc_codegen_ssa/src/mir/place.rs

+13-7
Original file line numberDiff line numberDiff line change
@@ -441,11 +441,19 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
441441
.find(|elem| matches!(elem.1, mir::ProjectionElem::Deref))
442442
{
443443
base = elem.0 + 1;
444-
self.codegen_consume(
444+
let cg_base = self.codegen_consume(
445445
bx,
446446
mir::PlaceRef { projection: &place_ref.projection[..elem.0], ..place_ref },
447-
)
448-
.deref(bx.cx())
447+
);
448+
449+
// a box with a non-zst allocator should not be directly dereferenced
450+
if cg_base.layout.ty.is_box() && !cg_base.layout.field(cx, 1).is_zst() {
451+
let ptr = cg_base.extract_field(bx, 0).extract_field(bx, 0);
452+
453+
ptr.deref(bx.cx())
454+
} else {
455+
cg_base.deref(bx.cx())
456+
}
449457
} else {
450458
bug!("using operand local {:?} as place", place_ref);
451459
}
@@ -454,10 +462,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
454462
for elem in place_ref.projection[base..].iter() {
455463
cg_base = match elem.clone() {
456464
mir::ProjectionElem::Deref => {
457-
// custom allocators can change box's abi, making it unable to be derefed directly
458-
if cg_base.layout.ty.is_box()
459-
&& matches!(cg_base.layout.abi, Abi::Aggregate { .. } | Abi::Uninhabited)
460-
{
465+
// a box with a non-zst allocator should not be directly dereferenced
466+
if cg_base.layout.ty.is_box() && !cg_base.layout.field(cx, 1).is_zst() {
461467
let ptr = cg_base.project_field(bx, 0).project_field(bx, 0);
462468

463469
bx.load_operand(ptr).deref(bx.cx())

‎src/test/ui/box/issue-95036.rs

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// compile-flags: -O
2+
// build-pass
3+
4+
#![feature(allocator_api, bench_black_box)]
5+
6+
#[inline(never)]
7+
pub fn by_ref(node: &mut Box<[u8; 1], &std::alloc::Global>) {
8+
node[0] = 9u8;
9+
}
10+
11+
pub fn main() {
12+
let mut node = Box::new_in([5u8], &std::alloc::Global);
13+
node[0] = 7u8;
14+
15+
std::hint::black_box(node);
16+
17+
let mut node = Box::new_in([5u8], &std::alloc::Global);
18+
19+
by_ref(&mut node);
20+
21+
std::hint::black_box(node);
22+
}

0 commit comments

Comments
 (0)