|
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