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
This commit is contained in:
commit
419a101d9c
1 changed files with 14 additions and 7 deletions
|
@ -504,15 +504,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(());
|
||||
}
|
||||
}
|
||||
|
@ -521,7 +520,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!
|
||||
|
@ -542,6 +542,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);
|
||||
|
|
Loading…
Reference in a new issue