Skip to content

Commit 8de72e4

Browse files
committed
interpret: avoid a long-lived PlaceTy in stack frames
1 parent 7606c13 commit 8de72e4

File tree

2 files changed

+10
-3
lines changed

2 files changed

+10
-3
lines changed

compiler/rustc_const_eval/src/interpret/eval_context.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ pub struct Frame<'mir, 'tcx, Prov: Provenance = CtfeProvenance, Extra = ()> {
108108

109109
/// The location where the result of the current stack frame should be written to,
110110
/// and its layout in the caller.
111-
pub return_place: PlaceTy<'tcx, Prov>,
111+
pub return_place: MPlaceTy<'tcx, Prov>,
112112

113113
/// The list of locals for this stack frame, stored in order as
114114
/// `[return_ptr, arguments..., variables..., temporaries...]`.
@@ -777,12 +777,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
777777
trace!("body: {:#?}", body);
778778
let dead_local = LocalState { value: LocalValue::Dead, layout: Cell::new(None) };
779779
let locals = IndexVec::from_elem(dead_local, &body.local_decls);
780+
let return_place = self.force_allocation(return_place)?; // avoid a long-lived `PlaceTy`
780781
// First push a stack frame so we have access to the local args
781782
let pre_frame = Frame {
782783
body,
783784
loc: Right(body.span), // Span used for errors caused during preamble.
784785
return_to_block,
785-
return_place: return_place.clone(),
786+
return_place,
786787
locals,
787788
instance,
788789
tracing_span: SpanGuard::new(),
@@ -912,7 +913,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
912913
} else {
913914
self.copy_op_allow_transmute(&op, &dest)
914915
};
915-
trace!("return value: {:?}", self.dump_place(&dest));
916+
trace!("return value: {:?}", self.dump_place(&dest.into()));
916917
// We delay actually short-circuiting on this error until *after* the stack frame is
917918
// popped, since we want this error to be attributed to the caller, whose type defines
918919
// this transmute.

compiler/rustc_const_eval/src/interpret/place.rs

+6
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,12 @@ pub(super) enum Place<Prov: Provenance = CtfeProvenance> {
194194
Local { frame: usize, local: mir::Local, offset: Option<Size> },
195195
}
196196

197+
/// An evaluated place, together with its type.
198+
///
199+
/// This may reference a stack frame by its index, so `PlaceTy` should generally not be kept around
200+
/// for longer than a single operation. Popping and then pushing a stack frame can make `PlaceTy`
201+
/// point to the wrong destination. If the interpreter has multiple stacks, stack switching will
202+
/// also invalidate a `PlaceTy`.
197203
#[derive(Clone)]
198204
pub struct PlaceTy<'tcx, Prov: Provenance = CtfeProvenance> {
199205
place: Place<Prov>, // Keep this private; it helps enforce invariants.

0 commit comments

Comments
 (0)