diff options
| author | Dylan DPC <99973273+Dylan-DPC@users.noreply.github.com> | 2022-03-28 20:41:51 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-03-28 20:41:51 +0200 |
| commit | ce319ac1a2a6af741cb7c4b574c7d0d730f899c4 (patch) | |
| tree | 19b6c1341b5634f1a0acdab709647620f5a4f045 /compiler | |
| parent | e10d5039bcc5648ae44390968ebc7568ff9db1ac (diff) | |
| parent | 09ccc63624f627e44f13c480c934b4d28a845258 (diff) | |
| download | rust-ce319ac1a2a6af741cb7c4b574c7d0d730f899c4.tar.gz rust-ce319ac1a2a6af741cb7c4b574c7d0d730f899c4.zip | |
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.
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/place.rs | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs index 2b8fa3be56d..17cfb6c5dfb 100644 --- a/compiler/rustc_codegen_ssa/src/mir/place.rs +++ b/compiler/rustc_codegen_ssa/src/mir/place.rs @@ -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); } @@ -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()) |
