Skip to content

Commit bcf82ef

Browse files
committed
deallocate locals before validation, to catch dangling references
1 parent 1d808d1 commit bcf82ef

File tree

1 file changed

+19
-11
lines changed

1 file changed

+19
-11
lines changed

src/librustc_mir/interpret/eval_context.rs

+19-11
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,24 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
492492
let frame = self.stack.pop().expect(
493493
"tried to pop a stack frame, but there were none",
494494
);
495-
// Validate the return value.
495+
// Abort early if we do not want to clean up: We also avoid validation in that case,
496+
// because this is CTFE and the final value will be thoroughly validated anyway.
497+
match frame.return_to_block {
498+
StackPopCleanup::Goto(_) => {},
499+
StackPopCleanup::None { cleanup } => {
500+
if !cleanup {
501+
assert!(self.stack.is_empty(), "only the topmost frame should ever be leaked");
502+
// Leak the locals, skip validation.
503+
return Ok(());
504+
}
505+
}
506+
}
507+
// Deallocate all locals that are backed by an allocation.
508+
for local in frame.locals {
509+
self.deallocate_local(local)?;
510+
}
511+
// Validate the return value. Do this after deallocating so that we catch dangling
512+
// references.
496513
if let Some(return_place) = frame.return_place {
497514
if M::enforce_validity(self) {
498515
// Data got changed, better make sure it matches the type!
@@ -518,16 +535,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
518535
StackPopCleanup::Goto(block) => {
519536
self.goto_block(block)?;
520537
}
521-
StackPopCleanup::None { cleanup } => {
522-
if !cleanup {
523-
// Leak the locals.
524-
return Ok(());
525-
}
526-
}
527-
}
528-
// Deallocate all locals that are backed by an allocation.
529-
for local in frame.locals {
530-
self.deallocate_local(local)?;
538+
StackPopCleanup::None { .. } => {}
531539
}
532540

533541
if self.stack.len() > 1 { // FIXME should be "> 0", printing topmost frame crashes rustc...

0 commit comments

Comments
 (0)