From caf3cc1fc88430caa61a8f1ae0262c3489a6481a Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Mon, 28 Oct 2019 22:44:30 -0400 Subject: Add explicit Miri support to libpanic_unwind --- src/libcore/intrinsics.rs | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/libcore') diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index 3db85d05d7a..f4a1ff0dd00 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -1348,6 +1348,11 @@ extern "rust-intrinsic" { /// See documentation of `<*const T>::offset_from` for details. #[cfg(not(bootstrap))] pub fn ptr_offset_from(ptr: *const T, base: *const T) -> isize; + + /// Internal hook used by Miri to implement unwinding. + /// Perma-unstable: do not use + #[cfg(not(bootstrap))] + pub fn miri_start_panic(data: *mut (dyn crate::any::Any + Send)) -> !; } // Some functions are defined here because they accidentally got made -- cgit 1.4.1-3-g733a5 From fe88fc03c50be57e1dc12cf308c45dc9c8d6473a Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 29 Oct 2019 17:31:54 -0400 Subject: Fix up intrinsic implementation --- src/libcore/intrinsics.rs | 2 +- src/libpanic_unwind/miri.rs | 8 ++++++-- src/librustc_codegen_ssa/mir/block.rs | 10 ++++++++++ src/librustc_typeck/check/intrinsic.rs | 4 ++++ 4 files changed, 21 insertions(+), 3 deletions(-) (limited to 'src/libcore') diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index f4a1ff0dd00..0cfe5595af5 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -1352,7 +1352,7 @@ extern "rust-intrinsic" { /// Internal hook used by Miri to implement unwinding. /// Perma-unstable: do not use #[cfg(not(bootstrap))] - pub fn miri_start_panic(data: *mut (dyn crate::any::Any + Send)) -> !; + pub fn miri_start_panic(data: u128) -> !; } // Some functions are defined here because they accidentally got made diff --git a/src/libpanic_unwind/miri.rs b/src/libpanic_unwind/miri.rs index a2d52638e8b..3b4203c3c6d 100644 --- a/src/libpanic_unwind/miri.rs +++ b/src/libpanic_unwind/miri.rs @@ -1,9 +1,13 @@ +use core::any::Any; +use alloc::boxed::Box; + pub fn payload() -> *mut u8 { core::ptr::null_mut() } -pub unsafe fn panic(data: Box) -> u32 { - core::intrinsics::miri_start_panic(Box::into_raw(data)) +pub unsafe fn panic(data: Box) -> ! { + let raw_val = core::mem::transmute::<_, u128>(Box::into_raw(data)); + core::intrinsics::miri_start_panic(raw_val) } pub unsafe fn cleanup(ptr: *mut u8) -> Box { diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index 13cd202158b..9361a7c3ea4 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -528,6 +528,16 @@ 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) + if intrinsic == Some("miri_start_panic") { + bx.abort(); + bx.unreachable(); + return; + } + // Emit a panic or a no-op for `panic_if_uninhabited`. if intrinsic == Some("panic_if_uninhabited") { let ty = instance.unwrap().substs.type_at(0); diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 1a1b98f582f..24b589df63a 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -384,6 +384,10 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem) { (1, vec![ tcx.mk_mut_ptr(param(0)), param(0) ], tcx.mk_unit()) } + "miri_start_panic" => { + (0, vec![tcx.types.u128], tcx.types.never) + } + ref other => { struct_span_err!(tcx.sess, it.span, E0093, "unrecognized intrinsic function: `{}`", -- cgit 1.4.1-3-g733a5 From 848e1d827e9a76f16cbb6d3f777edd6242390906 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 29 Oct 2019 18:23:36 -0400 Subject: More work on miri_start_panic --- src/libcore/intrinsics.rs | 7 ++++++- src/libpanic_unwind/miri.rs | 10 +++++++++- src/librustc_typeck/check/intrinsic.rs | 2 +- 3 files changed, 16 insertions(+), 3 deletions(-) (limited to 'src/libcore') diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index 0cfe5595af5..9a4c81f699b 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -1352,7 +1352,12 @@ extern "rust-intrinsic" { /// Internal hook used by Miri to implement unwinding. /// Perma-unstable: do not use #[cfg(not(bootstrap))] - pub fn miri_start_panic(data: u128) -> !; + // Note that the type is data is pretty arbitrary: + // we just need something that's guarnateed to be a fat + // pointer. Using `*mut [()]` instead of the actual type + // `*mut (Any + Send)` allows us to avoid making `Any` and `Send` + // lang items + pub fn miri_start_panic(data: *mut [()]) -> !; } // Some functions are defined here because they accidentally got made diff --git a/src/libpanic_unwind/miri.rs b/src/libpanic_unwind/miri.rs index 3b4203c3c6d..90fd5cafc37 100644 --- a/src/libpanic_unwind/miri.rs +++ b/src/libpanic_unwind/miri.rs @@ -6,7 +6,7 @@ pub fn payload() -> *mut u8 { } pub unsafe fn panic(data: Box) -> ! { - let raw_val = core::mem::transmute::<_, u128>(Box::into_raw(data)); + let raw_val: *mut [()] = core::mem::transmute::<*mut (dyn Any + Send), _>(Box::into_raw(data)); core::intrinsics::miri_start_panic(raw_val) } @@ -14,3 +14,11 @@ pub unsafe fn cleanup(ptr: *mut u8) -> Box { 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() } +} diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 24b589df63a..50985a3a232 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -385,7 +385,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem) { } "miri_start_panic" => { - (0, vec![tcx.types.u128], tcx.types.never) + (0, vec![tcx.mk_mut_ptr(tcx.mk_slice(tcx.mk_unit()))], tcx.types.never) } ref other => { -- cgit 1.4.1-3-g733a5 From 5553476d490741efc8e3049401152d5d4ce6a934 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 29 Oct 2019 18:48:29 -0400 Subject: Use proper intrinsic type --- src/libcore/intrinsics.rs | 7 +------ src/libpanic_unwind/miri.rs | 3 +-- src/librustc_typeck/check/intrinsic.rs | 4 +++- 3 files changed, 5 insertions(+), 9 deletions(-) (limited to 'src/libcore') diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index 9a4c81f699b..686d0bbefc8 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -1352,12 +1352,7 @@ extern "rust-intrinsic" { /// Internal hook used by Miri to implement unwinding. /// Perma-unstable: do not use #[cfg(not(bootstrap))] - // Note that the type is data is pretty arbitrary: - // we just need something that's guarnateed to be a fat - // pointer. Using `*mut [()]` instead of the actual type - // `*mut (Any + Send)` allows us to avoid making `Any` and `Send` - // lang items - pub fn miri_start_panic(data: *mut [()]) -> !; + 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/miri.rs b/src/libpanic_unwind/miri.rs index 90fd5cafc37..254a9383b42 100644 --- a/src/libpanic_unwind/miri.rs +++ b/src/libpanic_unwind/miri.rs @@ -6,8 +6,7 @@ pub fn payload() -> *mut u8 { } pub unsafe fn panic(data: Box) -> ! { - let raw_val: *mut [()] = core::mem::transmute::<*mut (dyn Any + Send), _>(Box::into_raw(data)); - core::intrinsics::miri_start_panic(raw_val) + core::intrinsics::miri_start_panic(Box::into_raw(data)) } pub unsafe fn cleanup(ptr: *mut u8) -> Box { diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 50985a3a232..627b0bb0e69 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -385,7 +385,9 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem) { } "miri_start_panic" => { - (0, vec![tcx.mk_mut_ptr(tcx.mk_slice(tcx.mk_unit()))], tcx.types.never) + // TODO - the relevant types aren't lang items, + // so it's not trivial to check this + return; } ref other => { -- cgit 1.4.1-3-g733a5