Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 14 additions & 7 deletions src/librustc_mir/interpret/eval_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -492,15 +492,14 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
let frame = self.stack.pop().expect(
"tried to pop a stack frame, but there were none",
);
// Abort early if we do not want to clean up: We also avoid validation in that case,
// because this is CTFE and the final value will be thoroughly validated anyway.
match frame.return_to_block {
StackPopCleanup::Goto(block) => {
self.goto_block(block)?;
}
StackPopCleanup::Goto(_) => {},
StackPopCleanup::None { cleanup } => {
if !cleanup {
// Leak the locals. Also skip validation, this is only used by
// static/const computation which does its own (stronger) final
// validation.
assert!(self.stack.is_empty(), "only the topmost frame should ever be leaked");
// Leak the locals, skip validation.
return Ok(());
}
}
Expand All @@ -509,7 +508,8 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
for local in frame.locals {
self.deallocate_local(local)?;
}
// Validate the return value.
// Validate the return value. Do this after deallocating so that we catch dangling
// references.
if let Some(return_place) = frame.return_place {
if M::enforce_validity(self) {
// Data got changed, better make sure it matches the type!
Expand All @@ -530,6 +530,13 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
// Uh, that shouldn't happen... the function did not intend to return
return err!(Unreachable);
}
// Jump to new block -- *after* validation so that the spans make more sense.
match frame.return_to_block {
StackPopCleanup::Goto(block) => {
self.goto_block(block)?;
}
StackPopCleanup::None { .. } => {}
}

if self.stack.len() > 1 { // FIXME should be "> 0", printing topmost frame crashes rustc...
debug!("CONTINUING({}) {}", self.cur_frame(), self.frame().instance);
Expand Down