Skip to content

Commit 419a101

Browse files
authored
Rollup merge of #56022 - RalfJung:validate-before-jump, r=oli-obk
When popping in CTFE, perform validation before jumping to next statement to have a better span for the error Currently, when validating the return value fails, the span points at the next statement after the call. That does not make much sense. r? @oli-obk
2 parents 12f6a42 + bcf82ef commit 419a101

File tree

1 file changed

+14
-7
lines changed

1 file changed

+14
-7
lines changed

src/librustc_mir/interpret/eval_context.rs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -504,15 +504,14 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
504504
let frame = self.stack.pop().expect(
505505
"tried to pop a stack frame, but there were none",
506506
);
507+
// Abort early if we do not want to clean up: We also avoid validation in that case,
508+
// because this is CTFE and the final value will be thoroughly validated anyway.
507509
match frame.return_to_block {
508-
StackPopCleanup::Goto(block) => {
509-
self.goto_block(block)?;
510-
}
510+
StackPopCleanup::Goto(_) => {},
511511
StackPopCleanup::None { cleanup } => {
512512
if !cleanup {
513-
// Leak the locals. Also skip validation, this is only used by
514-
// static/const computation which does its own (stronger) final
515-
// validation.
513+
assert!(self.stack.is_empty(), "only the topmost frame should ever be leaked");
514+
// Leak the locals, skip validation.
516515
return Ok(());
517516
}
518517
}
@@ -521,7 +520,8 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
521520
for local in frame.locals {
522521
self.deallocate_local(local)?;
523522
}
524-
// Validate the return value.
523+
// Validate the return value. Do this after deallocating so that we catch dangling
524+
// references.
525525
if let Some(return_place) = frame.return_place {
526526
if M::enforce_validity(self) {
527527
// Data got changed, better make sure it matches the type!
@@ -542,6 +542,13 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
542542
// Uh, that shouldn't happen... the function did not intend to return
543543
return err!(Unreachable);
544544
}
545+
// Jump to new block -- *after* validation so that the spans make more sense.
546+
match frame.return_to_block {
547+
StackPopCleanup::Goto(block) => {
548+
self.goto_block(block)?;
549+
}
550+
StackPopCleanup::None { .. } => {}
551+
}
545552

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

0 commit comments

Comments
 (0)