]> git.lizzy.rs Git - rust.git/blobdiff - src/shims/panic.rs
Auto merge of #2189 - RalfJung:clippy, r=RalfJung
[rust.git] / src / shims / panic.rs
index 06a434727b5fc3a9ff35b5af1b83f25cd19ac989..ed6e72591dd002e331b3ab45193573854486dfc4 100644 (file)
@@ -15,6 +15,7 @@
 
 use rustc_ast::Mutability;
 use rustc_middle::{mir, ty};
+use rustc_span::Symbol;
 use rustc_target::spec::abi::Abi;
 use rustc_target::spec::PanicStrategy;
 
@@ -40,27 +41,25 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
     /// by libpanic_unwind to delegate the actual unwinding process to Miri.
     fn handle_miri_start_panic(
         &mut self,
+        abi: Abi,
+        link_name: Symbol,
         args: &[OpTy<'tcx, Tag>],
-        unwind: Option<mir::BasicBlock>,
+        unwind: StackPopUnwind,
     ) -> InterpResult<'tcx> {
         let this = self.eval_context_mut();
 
         trace!("miri_start_panic: {:?}", this.frame().instance);
-        // Make sure we only start unwinding when this matches our panic strategy.
-        if this.tcx.sess.panic_strategy() != PanicStrategy::Unwind {
-            throw_ub_format!("unwinding despite panic=abort");
-        }
 
         // Get the raw pointer stored in arg[0] (the panic payload).
-        let &[ref payload] = check_arg_count(args)?;
+        let [payload] = this.check_shim(abi, Abi::Rust, link_name, args)?;
         let payload = this.read_scalar(payload)?.check_init()?;
         let thread = this.active_thread_mut();
         assert!(thread.panic_payload.is_none(), "the panic runtime should avoid double-panics");
         thread.panic_payload = Some(payload);
 
         // Jump to the unwind block to begin unwinding.
-        this.unwind_to_block(unwind);
-        return Ok(());
+        this.unwind_to_block(unwind)?;
+        Ok(())
     }
 
     /// Handles the `try` intrinsic, the underlying implementation of `std::panicking::try`.
@@ -84,22 +83,22 @@ fn handle_try(
         // a pointer to `Box<dyn Any + Send + 'static>`.
 
         // Get all the arguments.
-        let &[ref try_fn, ref data, ref catch_fn] = check_arg_count(args)?;
-        let try_fn = this.read_scalar(try_fn)?.check_init()?;
+        let [try_fn, data, catch_fn] = check_arg_count(args)?;
+        let try_fn = this.read_pointer(try_fn)?;
         let data = this.read_scalar(data)?.check_init()?;
         let catch_fn = this.read_scalar(catch_fn)?.check_init()?;
 
         // Now we make a function call, and pass `data` as first and only argument.
-        let f_instance = this.memory.get_fn(try_fn)?.as_instance()?;
+        let f_instance = this.get_ptr_fn(try_fn)?.as_instance()?;
         trace!("try_fn: {:?}", f_instance);
-        let ret_place = MPlaceTy::dangling(this.machine.layouts.unit, this).into();
+        let ret_place = MPlaceTy::dangling(this.machine.layouts.unit).into();
         this.call_function(
             f_instance,
             Abi::Rust,
             &[data.into()],
-            Some(&ret_place),
+            &ret_place,
             // Directly return to caller.
-            StackPopCleanup::Goto { ret: Some(ret), unwind: None },
+            StackPopCleanup::Goto { ret: Some(ret), unwind: StackPopUnwind::Skip },
         )?;
 
         // We ourselves will return `0`, eventually (will be overwritten if we catch a panic).
@@ -113,7 +112,7 @@ fn handle_try(
                 Some(CatchUnwindData { catch_fn, data, dest: *dest, ret });
         }
 
-        return Ok(());
+        Ok(())
     }
 
     fn handle_stack_pop(
@@ -124,7 +123,7 @@ fn handle_stack_pop(
         let this = self.eval_context_mut();
 
         trace!("handle_stack_pop(extra = {:?}, unwinding = {})", extra, unwinding);
-        if let Some(stacked_borrows) = &this.memory.extra.stacked_borrows {
+        if let Some(stacked_borrows) = &this.machine.stacked_borrows {
             stacked_borrows.borrow_mut().end_call(extra.call_id);
         }
 
@@ -146,16 +145,17 @@ fn handle_stack_pop(
             let payload = this.active_thread_mut().panic_payload.take().unwrap();
 
             // Push the `catch_fn` stackframe.
-            let f_instance = this.memory.get_fn(catch_unwind.catch_fn)?.as_instance()?;
+            let f_instance =
+                this.get_ptr_fn(this.scalar_to_ptr(catch_unwind.catch_fn)?)?.as_instance()?;
             trace!("catch_fn: {:?}", f_instance);
-            let ret_place = MPlaceTy::dangling(this.machine.layouts.unit, this).into();
+            let ret_place = MPlaceTy::dangling(this.machine.layouts.unit).into();
             this.call_function(
                 f_instance,
                 Abi::Rust,
                 &[catch_unwind.data.into(), payload.into()],
-                Some(&ret_place),
+                &ret_place,
                 // Directly return to caller of `try`.
-                StackPopCleanup::Goto { ret: Some(catch_unwind.ret), unwind: None },
+                StackPopCleanup::Goto { ret: Some(catch_unwind.ret), unwind: StackPopUnwind::Skip },
             )?;
 
             // We pushed a new stack frame, the engine should not do any jumping now!
@@ -165,8 +165,8 @@ fn handle_stack_pop(
         }
     }
 
-    /// Starta a panic in the interpreter with the given message as payload.
-    fn start_panic(&mut self, msg: &str, unwind: Option<mir::BasicBlock>) -> InterpResult<'tcx> {
+    /// Start a panic in the interpreter with the given message as payload.
+    fn start_panic(&mut self, msg: &str, unwind: StackPopUnwind) -> InterpResult<'tcx> {
         let this = self.eval_context_mut();
 
         // First arg: message.
@@ -178,8 +178,8 @@ fn start_panic(&mut self, msg: &str, unwind: Option<mir::BasicBlock>) -> InterpR
         this.call_function(
             panic,
             Abi::Rust,
-            &[msg.to_ref()],
-            None,
+            &[msg.to_ref(this)],
+            &MPlaceTy::dangling(this.machine.layouts.unit).into(),
             StackPopCleanup::Goto { ret: None, unwind },
         )
     }
@@ -208,13 +208,25 @@ fn assert_panic(
                     panic_bounds_check,
                     Abi::Rust,
                     &[index.into(), len.into()],
-                    None,
-                    StackPopCleanup::Goto { ret: None, unwind },
+                    &MPlaceTy::dangling(this.machine.layouts.unit).into(),
+                    StackPopCleanup::Goto {
+                        ret: None,
+                        unwind: match unwind {
+                            Some(cleanup) => StackPopUnwind::Cleanup(cleanup),
+                            None => StackPopUnwind::Skip,
+                        },
+                    },
                 )?;
             }
             _ => {
                 // Forward everything else to `panic` lang item.
-                this.start_panic(msg.description(), unwind)?;
+                this.start_panic(
+                    msg.description(),
+                    match unwind {
+                        Some(cleanup) => StackPopUnwind::Cleanup(cleanup),
+                        None => StackPopUnwind::Skip,
+                    },
+                )?;
             }
         }
         Ok(())