Rollup merge of #95328 - DrMeepster:box_gep_err, r=oli-obk
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.
This commit is contained in:
commit
ce319ac1a2
2 changed files with 35 additions and 7 deletions
|
@ -441,11 +441,19 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
.find(|elem| matches!(elem.1, mir::ProjectionElem::Deref))
|
.find(|elem| matches!(elem.1, mir::ProjectionElem::Deref))
|
||||||
{
|
{
|
||||||
base = elem.0 + 1;
|
base = elem.0 + 1;
|
||||||
self.codegen_consume(
|
let cg_base = self.codegen_consume(
|
||||||
bx,
|
bx,
|
||||||
mir::PlaceRef { projection: &place_ref.projection[..elem.0], ..place_ref },
|
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 {
|
} else {
|
||||||
bug!("using operand local {:?} as place", place_ref);
|
bug!("using operand local {:?} as place", place_ref);
|
||||||
}
|
}
|
||||||
|
@ -454,10 +462,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
for elem in place_ref.projection[base..].iter() {
|
for elem in place_ref.projection[base..].iter() {
|
||||||
cg_base = match elem.clone() {
|
cg_base = match elem.clone() {
|
||||||
mir::ProjectionElem::Deref => {
|
mir::ProjectionElem::Deref => {
|
||||||
// custom allocators can change box's abi, making it unable to be derefed directly
|
// a box with a non-zst allocator should not be directly dereferenced
|
||||||
if cg_base.layout.ty.is_box()
|
if cg_base.layout.ty.is_box() && !cg_base.layout.field(cx, 1).is_zst() {
|
||||||
&& matches!(cg_base.layout.abi, Abi::Aggregate { .. } | Abi::Uninhabited)
|
|
||||||
{
|
|
||||||
let ptr = cg_base.project_field(bx, 0).project_field(bx, 0);
|
let ptr = cg_base.project_field(bx, 0).project_field(bx, 0);
|
||||||
|
|
||||||
bx.load_operand(ptr).deref(bx.cx())
|
bx.load_operand(ptr).deref(bx.cx())
|
||||||
|
|
22
src/test/ui/box/issue-95036.rs
Normal file
22
src/test/ui/box/issue-95036.rs
Normal file
|
@ -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);
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue