|
1 | | -use rustc_middle::mir::{self, NonDivergingIntrinsic, RETURN_PLACE, StmtDebugInfo}; |
2 | | -use rustc_middle::{bug, span_bug}; |
3 | | -use rustc_target::callconv::PassMode; |
| 1 | +use rustc_middle::mir::{self, NonDivergingIntrinsic, StmtDebugInfo}; |
| 2 | +use rustc_middle::span_bug; |
4 | 3 | use tracing::instrument; |
5 | 4 |
|
6 | 5 | use super::{FunctionCx, LocalRef}; |
7 | | -use crate::common::TypeKind; |
8 | | -use crate::mir::place::PlaceRef; |
9 | 6 | use crate::traits::*; |
10 | 7 |
|
11 | 8 | impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { |
@@ -110,48 +107,28 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { |
110 | 107 | match debuginfo { |
111 | 108 | StmtDebugInfo::AssignRef(dest, place) => { |
112 | 109 | let local_ref = match self.locals[place.local] { |
113 | | - LocalRef::Place(place_ref) | LocalRef::UnsizedPlace(place_ref) => { |
114 | | - Some(place_ref) |
| 110 | + // For an rvalue like `&(_1.1)`, when `BackendRepr` is `BackendRepr::Memory`, we allocate a block of memory to this place. |
| 111 | + // The place is an indirect pointer, we can refer to it directly. |
| 112 | + LocalRef::Place(place_ref) => Some((place_ref, place.projection.as_slice())), |
| 113 | + // For an rvalue like `&((*_1).1)`, we are calculating the address of `_1.1`. |
| 114 | + // The deref projection is no-op here. |
| 115 | + LocalRef::Operand(operand_ref) if place.is_indirect_first_projection() => { |
| 116 | + Some((operand_ref.deref(bx.cx()), &place.projection[1..])) |
115 | 117 | } |
116 | | - LocalRef::Operand(operand_ref) => operand_ref |
117 | | - .val |
118 | | - .try_pointer_parts() |
119 | | - .map(|(pointer, _)| PlaceRef::new_sized(pointer, operand_ref.layout)), |
120 | | - LocalRef::PendingOperand => None, |
| 118 | + // For an rvalue like `&1`, when `BackendRepr` is `BackendRepr::Scalar`, |
| 119 | + // we cannot get the address. |
| 120 | + // N.B. `non_ssa_locals` returns that this is an SSA local. |
| 121 | + LocalRef::Operand(_) => None, |
| 122 | + LocalRef::UnsizedPlace(_) | LocalRef::PendingOperand => None, |
121 | 123 | } |
122 | | - .filter(|place_ref| { |
123 | | - // For the reference of an argument (e.x. `&_1`), it's only valid if the pass mode is indirect, and its reference is |
124 | | - // llval. |
125 | | - let local_ref_pass_mode = place.as_local().and_then(|local| { |
126 | | - if local == RETURN_PLACE { |
127 | | - None |
128 | | - } else { |
129 | | - self.fn_abi.args.get(local.as_usize() - 1).map(|arg| &arg.mode) |
130 | | - } |
131 | | - }); |
132 | | - matches!(local_ref_pass_mode, Some(&PassMode::Indirect {..}) | None) && |
| 124 | + .filter(|(_, projection)| { |
133 | 125 | // Drop unsupported projections. |
134 | | - place.projection.iter().all(|p| p.can_use_in_debuginfo()) && |
135 | | - // Only pointers can be calculated addresses. |
136 | | - bx.type_kind(bx.val_ty(place_ref.val.llval)) == TypeKind::Pointer |
| 126 | + projection.iter().all(|p| p.can_use_in_debuginfo()) |
137 | 127 | }); |
138 | | - if let Some(local_ref) = local_ref { |
139 | | - let (base_layout, projection) = if place.is_indirect_first_projection() { |
140 | | - // For `_n = &((*_1).0: i32);`, we are calculating the address of `_1.0`, so |
141 | | - // we should drop the deref projection. |
142 | | - let projected_ty = local_ref |
143 | | - .layout |
144 | | - .ty |
145 | | - .builtin_deref(true) |
146 | | - .unwrap_or_else(|| bug!("deref of non-pointer {:?}", local_ref)); |
147 | | - let layout = bx.cx().layout_of(projected_ty); |
148 | | - (layout, &place.projection[1..]) |
149 | | - } else { |
150 | | - (local_ref.layout, place.projection.as_slice()) |
151 | | - }; |
152 | | - self.debug_new_val_to_local(bx, *dest, local_ref.val, base_layout, projection); |
| 128 | + if let Some((base, projection)) = local_ref { |
| 129 | + self.debug_new_val_to_local(bx, *dest, base, projection); |
153 | 130 | } else { |
154 | | - // If the address cannot be computed, use poison to indicate that the value has been optimized out. |
| 131 | + // If the address cannot be calculated, use poison to indicate that the value has been optimized out. |
155 | 132 | self.debug_poison_to_local(bx, *dest); |
156 | 133 | } |
157 | 134 | } |
|
0 commit comments