]> git.lizzy.rs Git - rust.git/commitdiff
Fix pop_stack_frame logic
authorJonas Schievink <jonasschievink@gmail.com>
Wed, 15 Apr 2020 23:32:05 +0000 (01:32 +0200)
committerJonas Schievink <jonasschievink@gmail.com>
Mon, 20 Apr 2020 19:18:20 +0000 (21:18 +0200)
src/librustc_mir/interpret/eval_context.rs

index 283f9e14251788a69b0a562f405a9cd6b6996985..d92c37b7debfe052cf7ef2096bc585ac76cec8fd 100644 (file)
@@ -724,10 +724,14 @@ pub(super) fn pop_stack_frame(&mut self, unwinding: bool) -> InterpResult<'tcx>
         let frame =
             self.stack_mut().pop().expect("tried to pop a stack frame, but there were none");
 
-        if let Some(return_place) = frame.return_place {
+        if !unwinding {
             // Copy the return value to the caller's stack frame.
-            let op = self.access_local(&frame, mir::RETURN_PLACE, None)?;
-            self.copy_op(op, return_place)?;
+            if let Some(return_place) = frame.return_place {
+                let op = self.access_local(&frame, mir::RETURN_PLACE, None)?;
+                self.copy_op(op, return_place)?;
+            } else {
+                throw_ub!(Unreachable);
+            }
         }
 
         // Now where do we jump next?
@@ -768,25 +772,6 @@ pub(super) fn pop_stack_frame(&mut self, unwinding: bool) -> InterpResult<'tcx>
             self.unwind_to_block(unwind);
         } else {
             // Follow the normal return edge.
-            // Validate the return value. Do this after deallocating so that we catch dangling
-            // references.
-            if let Some(return_place) = return_place {
-                if M::enforce_validity(self) {
-                    // Data got changed, better make sure it matches the type!
-                    // It is still possible that the return place held invalid data while
-                    // the function is running, but that's okay because nobody could have
-                    // accessed that same data from the "outside" to observe any broken
-                    // invariant -- that is, unless a function somehow has a ptr to
-                    // its return place... but the way MIR is currently generated, the
-                    // return place is always a local and then this cannot happen.
-                    self.validate_operand(self.place_to_op(return_place)?)?;
-                }
-            } else {
-                // Uh, that shouldn't happen... the function did not intend to return
-                throw_ub!(Unreachable);
-            }
-
-            // Jump to new block -- *after* validation so that the spans make more sense.
             if let Some(ret) = next_block {
                 self.return_to_block(ret)?;
             }