about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2019-12-02 09:34:12 +0100
committerGitHub <noreply@github.com>2019-12-02 09:34:12 +0100
commitb7f8b77eec41b47f5cb49bce53dc34c7e87269c7 (patch)
treee12baa06bbcdd5f2f48188de2e99435c268c8645
parentf32f56969c6c0e4d43b2ca9a6d5254c64ae1cd91 (diff)
parent02b66a19010c76e41805e65179e951ad1d41e0c7 (diff)
downloadrust-b7f8b77eec41b47f5cb49bce53dc34c7e87269c7.tar.gz
rust-b7f8b77eec41b47f5cb49bce53dc34c7e87269c7.zip
Rollup merge of #66822 - RalfJung:miri-panic, r=oli-obk
libunwind_panic: adjust miri panic hack

We adjust the Miri hack in libpanic_unwind such that even with `cfg(miri)`, we build a version of libpanic_unwind that actually works.

This is needed to resolve https://github.com/integer32llc/rust-playground/issues/548.

r? @oli-obk @alexcrichton
-rw-r--r--src/libcore/intrinsics.rs4
-rw-r--r--src/libpanic_unwind/lib.rs16
-rw-r--r--src/libpanic_unwind/miri.rs42
-rw-r--r--src/librustc_codegen_ssa/mir/block.rs15
4 files changed, 18 insertions, 59 deletions
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index e3dc5630c94..d4952f53bf7 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -1348,9 +1348,11 @@ extern "rust-intrinsic" {
     pub fn ptr_offset_from<T>(ptr: *const T, base: *const T) -> isize;
 
     /// Internal hook used by Miri to implement unwinding.
+    /// Compiles to a NOP during non-Miri codegen.
+    ///
     /// Perma-unstable: do not use
     #[cfg(not(bootstrap))]
-    pub fn miri_start_panic(data: *mut (dyn crate::any::Any + crate::marker::Send)) -> !;
+    pub fn miri_start_panic(data: *mut (dyn crate::any::Any + crate::marker::Send)) -> ();
 }
 
 // Some functions are defined here because they accidentally got made
diff --git a/src/libpanic_unwind/lib.rs b/src/libpanic_unwind/lib.rs
index 0c834e5c2a0..3a14197c77b 100644
--- a/src/libpanic_unwind/lib.rs
+++ b/src/libpanic_unwind/lib.rs
@@ -36,10 +36,7 @@ use core::raw;
 use core::panic::BoxMeUp;
 
 cfg_if::cfg_if! {
-    if #[cfg(miri)] {
-        #[path = "miri.rs"]
-        mod imp;
-    } else if #[cfg(target_os = "emscripten")] {
+    if #[cfg(target_os = "emscripten")] {
         #[path = "emcc.rs"]
         mod imp;
     } else if #[cfg(target_arch = "wasm32")] {
@@ -94,5 +91,14 @@ pub unsafe extern "C" fn __rust_maybe_catch_panic(f: fn(*mut u8),
 #[unwind(allowed)]
 pub unsafe extern "C" fn __rust_start_panic(payload: usize) -> u32 {
     let payload = payload as *mut &mut dyn BoxMeUp;
-    imp::panic(Box::from_raw((*payload).take_box()))
+    let payload = (*payload).take_box();
+
+    // Miri panic support: cfg'd out of normal builds just to be sure.
+    // When going through normal codegen, `miri_start_panic` is a NOP, so the
+    // Miri-enabled sysroot still supports normal unwinding. But when executed in
+    // Miri, this line initiates unwinding.
+    #[cfg(miri)]
+    core::intrinsics::miri_start_panic(payload);
+
+    imp::panic(Box::from_raw(payload))
 }
diff --git a/src/libpanic_unwind/miri.rs b/src/libpanic_unwind/miri.rs
deleted file mode 100644
index f26c42fd4bc..00000000000
--- a/src/libpanic_unwind/miri.rs
+++ /dev/null
@@ -1,42 +0,0 @@
-#![allow(nonstandard_style)]
-
-use core::any::Any;
-use alloc::boxed::Box;
-
-pub fn payload() -> *mut u8 {
-    core::ptr::null_mut()
-}
-
-pub unsafe fn panic(data: Box<dyn Any + Send>) -> ! {
-    core::intrinsics::miri_start_panic(Box::into_raw(data))
-}
-
-pub unsafe fn cleanup(ptr: *mut u8) -> Box<dyn Any + Send> {
-    Box::from_raw(ptr)
-}
-
-// This is required by the compiler to exist (e.g., it's a lang item),
-// but is never used by Miri. Therefore, we just use a stub here
-#[lang = "eh_personality"]
-#[cfg(not(test))]
-fn rust_eh_personality() {
-    unsafe { core::intrinsics::abort() }
-}
-
-// The rest is required on *some* targets to exist (specifically, MSVC targets that use SEH).
-// We just add it on all targets. Copied from `seh.rs`.
-#[repr(C)]
-pub struct _TypeDescriptor {
-    pub pVFTable: *const u8,
-    pub spare: *mut u8,
-    pub name: [u8; 11],
-}
-
-const TYPE_NAME: [u8; 11] = *b"rust_panic\0";
-
-#[cfg_attr(not(test), lang = "eh_catch_typeinfo")]
-static mut TYPE_DESCRIPTOR: _TypeDescriptor = _TypeDescriptor {
-    pVFTable: core::ptr::null(),
-    spare: core::ptr::null_mut(),
-    name: TYPE_NAME,
-};
diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs
index 14be0e80fb4..d76392f7570 100644
--- a/src/librustc_codegen_ssa/mir/block.rs
+++ b/src/librustc_codegen_ssa/mir/block.rs
@@ -528,18 +528,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             _ => FnAbi::new(&bx, sig, &extra_args)
         };
 
-        // This should never be reachable at runtime:
-        // We should only emit a call to this intrinsic in #[cfg(miri)] mode,
-        // which means that we will never actually use the generate object files
-        // (we will just be interpreting the MIR)
-        //
-        // Note that we still need to be able to codegen *something* for this intrisnic:
-        // Miri currently uses Xargo to build a special libstd. As a side effect,
-        // we generate normal object files for libstd - while these are never used,
-        // we still need to be able to build them.
+        // For normal codegen, this Miri-specific intrinsic is just a NOP.
         if intrinsic == Some("miri_start_panic") {
-            bx.abort();
-            bx.unreachable();
+            let target = destination.as_ref().unwrap().1;
+            helper.maybe_sideeffect(self.mir, &mut bx, &[target]);
+            helper.funclet_br(self, &mut bx, target);
             return;
         }