From dc7e478d626269425870ef281dd8aee11a4b50ef Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Thu, 26 Dec 2019 10:02:21 -0500 Subject: [PATCH 01/20] Inline catching panics into std::catch_unwind This allows LLVM to inline the happy path, such that catching unwinding is zero-cost when no panic occurs. This also allows us to match the code generated by C++ try/catch. --- src/libpanic_abort/lib.rs | 13 ++----- src/libpanic_unwind/dummy.rs | 4 +- src/libpanic_unwind/emcc.rs | 4 +- src/libpanic_unwind/gcc.rs | 5 +-- src/libpanic_unwind/hermit.rs | 4 +- src/libpanic_unwind/lib.rs | 33 ++++------------- src/libpanic_unwind/seh.rs | 4 +- src/libstd/panicking.rs | 70 ++++++++++++++++++++++------------- 8 files changed, 60 insertions(+), 77 deletions(-) diff --git a/src/libpanic_abort/lib.rs b/src/libpanic_abort/lib.rs index db7c250e21157..ebc57860b9d4a 100644 --- a/src/libpanic_abort/lib.rs +++ b/src/libpanic_abort/lib.rs @@ -17,18 +17,11 @@ #![feature(panic_runtime)] #![feature(staged_api)] #![feature(rustc_attrs)] +#![feature(raw)] -// Rust's "try" function, but if we're aborting on panics we just call the -// function as there's nothing else we need to do here. #[rustc_std_internal_symbol] -pub unsafe extern "C" fn __rust_maybe_catch_panic( - f: fn(*mut u8), - data: *mut u8, - _data_ptr: *mut usize, - _vtable_ptr: *mut usize, -) -> u32 { - f(data); - 0 +pub unsafe extern "C" fn __rust_cleanup(_: *mut u8) -> core::raw::TraitObject { + unreachable!() } // "Leak" the payload and shim to the relevant abort on the platform in diff --git a/src/libpanic_unwind/dummy.rs b/src/libpanic_unwind/dummy.rs index 8675632638712..30593d3b88af9 100644 --- a/src/libpanic_unwind/dummy.rs +++ b/src/libpanic_unwind/dummy.rs @@ -6,9 +6,7 @@ use alloc::boxed::Box; use core::any::Any; use core::intrinsics; -pub fn payload() -> *mut u8 { - core::ptr::null_mut() -} +pub type Payload = *mut u8; pub unsafe fn cleanup(_ptr: *mut u8) -> Box { intrinsics::abort() diff --git a/src/libpanic_unwind/emcc.rs b/src/libpanic_unwind/emcc.rs index 9161d49959cf5..873135414bd9d 100644 --- a/src/libpanic_unwind/emcc.rs +++ b/src/libpanic_unwind/emcc.rs @@ -48,9 +48,7 @@ static EXCEPTION_TYPE_INFO: TypeInfo = TypeInfo { name: b"rust_panic\0".as_ptr(), }; -pub fn payload() -> *mut u8 { - ptr::null_mut() -} +pub type Payload = *mut u8; struct Exception { // This needs to be an Option because the object's lifetime follows C++ diff --git a/src/libpanic_unwind/gcc.rs b/src/libpanic_unwind/gcc.rs index 591ff9d7fdcaa..dd84a814f48b1 100644 --- a/src/libpanic_unwind/gcc.rs +++ b/src/libpanic_unwind/gcc.rs @@ -48,7 +48,6 @@ use alloc::boxed::Box; use core::any::Any; -use core::ptr; use crate::dwarf::eh::{self, EHAction, EHContext}; use libc::{c_int, uintptr_t}; @@ -83,9 +82,7 @@ pub unsafe fn panic(data: Box) -> u32 { } } -pub fn payload() -> *mut u8 { - ptr::null_mut() -} +pub type Payload = *mut u8; pub unsafe fn cleanup(ptr: *mut u8) -> Box { let exception = Box::from_raw(ptr as *mut Exception); diff --git a/src/libpanic_unwind/hermit.rs b/src/libpanic_unwind/hermit.rs index 2f53df2861d44..8ffb4bcd3df23 100644 --- a/src/libpanic_unwind/hermit.rs +++ b/src/libpanic_unwind/hermit.rs @@ -6,9 +6,7 @@ use alloc::boxed::Box; use core::any::Any; use core::ptr; -pub fn payload() -> *mut u8 { - ptr::null_mut() -} +pub type Payload = *mut u8; pub unsafe fn cleanup(_ptr: *mut u8) -> Box { extern "C" { diff --git a/src/libpanic_unwind/lib.rs b/src/libpanic_unwind/lib.rs index 6383ae39fb6db..60ddf70cea52f 100644 --- a/src/libpanic_unwind/lib.rs +++ b/src/libpanic_unwind/lib.rs @@ -22,20 +22,20 @@ #![feature(libc)] #![feature(nll)] #![feature(panic_unwind)] -#![feature(raw)] #![feature(staged_api)] #![feature(std_internals)] #![feature(unwind_attributes)] #![feature(abi_thiscall)] +#![feature(rustc_attrs)] +#![feature(raw)] #![panic_runtime] #![feature(panic_runtime)] use alloc::boxed::Box; -use core::intrinsics; -use core::mem; use core::panic::BoxMeUp; -use core::raw; +// If adding to this list, you should also look at libstd::panicking's identical +// list of Payload types and likely add to there as well. cfg_if::cfg_if! { if #[cfg(target_os = "emscripten")] { #[path = "emcc.rs"] @@ -69,28 +69,11 @@ extern "C" { mod dwarf; -// Entry point for catching an exception, implemented using the `try` intrinsic -// in the compiler. -// -// The interaction between the `payload` function and the compiler is pretty -// hairy and tightly coupled, for more information see the compiler's -// implementation of this. #[no_mangle] -pub unsafe extern "C" fn __rust_maybe_catch_panic( - f: fn(*mut u8), - data: *mut u8, - data_ptr: *mut usize, - vtable_ptr: *mut usize, -) -> u32 { - let mut payload = imp::payload(); - if intrinsics::r#try(f, data, &mut payload as *mut _ as *mut _) == 0 { - 0 - } else { - let obj = mem::transmute::<_, raw::TraitObject>(imp::cleanup(payload)); - *data_ptr = obj.data as usize; - *vtable_ptr = obj.vtable as usize; - 1 - } +pub unsafe extern "C" fn __rust_panic_cleanup(payload: *mut u8) -> core::raw::TraitObject { + let payload = payload as *mut imp::Payload; + let payload = *(payload); + core::mem::transmute(imp::cleanup(payload)) } // Entry point for raising an exception, just delegates to the platform-specific diff --git a/src/libpanic_unwind/seh.rs b/src/libpanic_unwind/seh.rs index 6f507e85e742c..6f464c1ab680e 100644 --- a/src/libpanic_unwind/seh.rs +++ b/src/libpanic_unwind/seh.rs @@ -308,9 +308,7 @@ pub unsafe fn panic(data: Box) -> u32 { _CxxThrowException(throw_ptr, &mut THROW_INFO as *mut _ as *mut _); } -pub fn payload() -> [u64; 2] { - [0; 2] -} +pub type Payload = [u64; 2]; pub unsafe fn cleanup(payload: [u64; 2]) -> Box { mem::transmute(raw::TraitObject { data: payload[0] as *mut _, vtable: payload[1] as *mut _ }) diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs index 8b12aaaa7e2fd..f71849fae34fa 100644 --- a/src/libstd/panicking.rs +++ b/src/libstd/panicking.rs @@ -12,9 +12,8 @@ use core::panic::{BoxMeUp, Location, PanicInfo}; use crate::any::Any; use crate::fmt; use crate::intrinsics; -use crate::mem::{self, ManuallyDrop}; +use crate::mem::{self, ManuallyDrop, MaybeUninit}; use crate::process; -use crate::raw; use crate::sync::atomic::{AtomicBool, Ordering}; use crate::sys::stdio::panic_output; use crate::sys_common::backtrace::{self, RustBacktrace}; @@ -29,6 +28,31 @@ use crate::io::set_panic; #[cfg(test)] use realstd::io::set_panic; +// This must be kept in sync with the implementations in libpanic_unwind. +// +// This is *not* checked in anyway; the compiler does not allow us to use a +// type/macro/anything from panic_unwind, since we're then linking in the +// panic_unwind runtime even during -Cpanic=abort. +// +// Essentially this must be the type of `imp::Payload` in libpanic_unwind. +cfg_if::cfg_if! { + if #[cfg(not(feature = "panic_unwind"))] { + type Payload = (); + } else if #[cfg(target_os = "emscripten")] { + type Payload = *mut u8; + } else if #[cfg(target_arch = "wasm32")] { + type Payload = *mut u8; + } else if #[cfg(target_os = "hermit")] { + type Payload = *mut u8; + } else if #[cfg(all(target_env = "msvc", target_arch = "aarch64"))] { + type Payload = *mut u8; + } else if #[cfg(target_env = "msvc")] { + type Payload = [u64; 2]; + } else { + type Payload = *mut u8; + } +} + // Binary interface to the panic runtime that the standard library depends on. // // The standard library is tagged with `#![needs_panic_runtime]` (introduced in @@ -41,12 +65,9 @@ use realstd::io::set_panic; // hook up these functions, but it is not this day! #[allow(improper_ctypes)] extern "C" { - fn __rust_maybe_catch_panic( - f: fn(*mut u8), - data: *mut u8, - data_ptr: *mut usize, - vtable_ptr: *mut usize, - ) -> u32; + /// The payload ptr here is actually the same as the payload ptr for the try + /// intrinsic (i.e., is really `*mut [u64; 2]` or `*mut *mut u8`). + fn __rust_panic_cleanup(payload: *mut u8) -> core::raw::TraitObject; /// `payload` is actually a `*mut &mut dyn BoxMeUp` but that would cause FFI warnings. /// It cannot be `Box` because the other end of this call does not depend @@ -250,9 +271,9 @@ pub unsafe fn r#try R>(f: F) -> Result> } // We do some sketchy operations with ownership here for the sake of - // performance. We can only pass pointers down to - // `__rust_maybe_catch_panic` (can't pass objects by value), so we do all - // the ownership tracking here manually using a union. + // performance. We can only pass pointers down to `do_call` (can't pass + // objects by value), so we do all the ownership tracking here manually + // using a union. // // We go through a transition where: // @@ -263,7 +284,7 @@ pub unsafe fn r#try R>(f: F) -> Result> // * If the closure successfully returns, we write the return value into the // data's return slot. Note that `ptr::write` is used as it's overwriting // uninitialized data. - // * Finally, when we come back out of the `__rust_maybe_catch_panic` we're + // * Finally, when we come back out of the `try` intrinsic we're // in one of two states: // // 1. The closure didn't panic, in which case the return value was @@ -274,27 +295,24 @@ pub unsafe fn r#try R>(f: F) -> Result> // // Once we stack all that together we should have the "most efficient' // method of calling a catch panic whilst juggling ownership. - let mut any_data = 0; - let mut any_vtable = 0; let mut data = Data { f: ManuallyDrop::new(f) }; - let r = __rust_maybe_catch_panic( - do_call::, - &mut data as *mut _ as *mut u8, - &mut any_data, - &mut any_vtable, - ); + let mut payload: MaybeUninit = MaybeUninit::uninit(); - return if r == 0 { + let data_ptr = &mut data as *mut _ as *mut u8; + let payload_ptr = payload.as_mut_ptr() as *mut _; + return if intrinsics::r#try(do_call::, data_ptr, payload_ptr) == 0 { Ok(ManuallyDrop::into_inner(data.r)) } else { - update_panic_count(-1); - Err(mem::transmute(raw::TraitObject { - data: any_data as *mut _, - vtable: any_vtable as *mut _, - })) + Err(cleanup(payload.assume_init())) }; + unsafe fn cleanup(mut payload: Payload) -> Box { + let obj = crate::mem::transmute(__rust_panic_cleanup(&mut payload as *mut _ as *mut u8)); + update_panic_count(-1); + obj + } + fn do_call R, R>(data: *mut u8) { unsafe { let data = data as *mut Data; From b77267308d500dea20aca948e396f36b8f6a91f0 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Thu, 26 Dec 2019 10:03:41 -0500 Subject: [PATCH 02/20] Avoid over-aligning the return value in the -Cpanic=abort case --- src/librustc_codegen_llvm/intrinsic.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 3d1e72e1c73d7..32f0154fa50bf 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -858,8 +858,10 @@ fn try_intrinsic( ) { if bx.sess().no_landing_pads() { bx.call(func, &[data], None); - let ptr_align = bx.tcx().data_layout.pointer_align.abi; - bx.store(bx.const_null(bx.type_i8p()), dest, ptr_align); + // Return 0 unconditionally from the intrinsic call; + // we can never unwind. + let ret_align = bx.tcx().data_layout.i32_align.abi; + bx.store(bx.const_i32(0), dest, ret_align); } else if wants_msvc_seh(bx.sess()) { codegen_msvc_try(bx, func, data, local_ptr, dest); } else { From 023c97e99887e1b4799122e7f6a807be1b4b1373 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Thu, 26 Dec 2019 10:37:48 -0500 Subject: [PATCH 03/20] Test catch_unwind vanishing We execpt the try intrinsic to be a direct call if in -Cpanic=abort mode, and that catch_unwind optimizes out if calling a function that does not unwind. --- src/test/codegen/catch-unwind.rs | 19 +++++++++++++++++++ src/test/codegen/try-panic-abort.rs | 17 +++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 src/test/codegen/catch-unwind.rs create mode 100644 src/test/codegen/try-panic-abort.rs diff --git a/src/test/codegen/catch-unwind.rs b/src/test/codegen/catch-unwind.rs new file mode 100644 index 0000000000000..3c9bc35d1c8bd --- /dev/null +++ b/src/test/codegen/catch-unwind.rs @@ -0,0 +1,19 @@ +// compile-flags: -O + +#![crate_type = "lib"] + +extern "C" { + fn bar(); +} + +// CHECK-LABEL: @foo +#[no_mangle] +pub unsafe fn foo() -> i32 { + // CHECK: call void @bar + // CHECK: ret i32 0 + std::panic::catch_unwind(|| { + bar(); + 0 + }) + .unwrap() +} diff --git a/src/test/codegen/try-panic-abort.rs b/src/test/codegen/try-panic-abort.rs new file mode 100644 index 0000000000000..9bc89a321576c --- /dev/null +++ b/src/test/codegen/try-panic-abort.rs @@ -0,0 +1,17 @@ +// compile-flags: -C panic=abort -O + +#![crate_type = "lib"] +#![feature(unwind_attributes, core_intrinsics)] + +extern "C" { + #[unwind(allow)] + fn bar(data: *mut u8); +} + +// CHECK-LABEL: @foo +#[no_mangle] +pub unsafe fn foo() -> i32 { + // CHECK: call void @bar + // CHECK: ret i32 0 + std::intrinsics::r#try(|x| bar(x), 0 as *mut u8, 0 as *mut u8) +} From 72c3098d31eede2f224bf33a958c09e196f0f835 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Thu, 26 Dec 2019 10:49:16 -0500 Subject: [PATCH 04/20] Ignore PAL lint for std::panicking --- src/tools/tidy/src/pal.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tools/tidy/src/pal.rs b/src/tools/tidy/src/pal.rs index dcd4c9e8ef7d9..31fc6f10e8296 100644 --- a/src/tools/tidy/src/pal.rs +++ b/src/tools/tidy/src/pal.rs @@ -59,6 +59,8 @@ const EXCEPTION_PATHS: &[&str] = &[ "src/libstd/sys_common/mod.rs", "src/libstd/sys_common/net.rs", "src/libstd/sys_common/backtrace.rs", + // panic_unwind shims + "src/libstd/panicking.rs", "src/libterm", // Not sure how to make this crate portable, but test crate needs it. "src/libtest", // Probably should defer to unstable `std::sys` APIs. "src/libstd/sync/mpsc", // some tests are only run on non-emscripten From 6bfd6ad62da09686e5e2a44aa1939a279f286e9c Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Thu, 26 Dec 2019 10:54:24 -0500 Subject: [PATCH 05/20] Mark cleanup cold --- src/libstd/panicking.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs index f71849fae34fa..3dd1f09e07656 100644 --- a/src/libstd/panicking.rs +++ b/src/libstd/panicking.rs @@ -307,6 +307,11 @@ pub unsafe fn r#try R>(f: F) -> Result> Err(cleanup(payload.assume_init())) }; + // We consider unwinding to be rare, so mark this function as cold. However, + // do not mark it no-inline -- that decision is best to leave to the + // optimizer (in most cases this function is not inlined even as a normal, + // non-cold function, though, as of the writing of this comment). + #[cold] unsafe fn cleanup(mut payload: Payload) -> Box { let obj = crate::mem::transmute(__rust_panic_cleanup(&mut payload as *mut _ as *mut u8)); update_panic_count(-1); From 05c97b9fd3307ac6f219f24d6ddc18813fb8a673 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Thu, 26 Dec 2019 19:37:14 +0100 Subject: [PATCH 06/20] Fix some minor issues --- src/libpanic_abort/lib.rs | 5 +++-- src/libpanic_unwind/lib.rs | 5 +++-- src/libstd/panicking.rs | 4 ++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/libpanic_abort/lib.rs b/src/libpanic_abort/lib.rs index ebc57860b9d4a..fe9196ef2314b 100644 --- a/src/libpanic_abort/lib.rs +++ b/src/libpanic_abort/lib.rs @@ -17,10 +17,11 @@ #![feature(panic_runtime)] #![feature(staged_api)] #![feature(rustc_attrs)] -#![feature(raw)] + +use core::any::Any; #[rustc_std_internal_symbol] -pub unsafe extern "C" fn __rust_cleanup(_: *mut u8) -> core::raw::TraitObject { +pub unsafe extern "C" fn __rust_panic_cleanup(_: *mut u8) -> *mut (dyn Any + Send + 'static) { unreachable!() } diff --git a/src/libpanic_unwind/lib.rs b/src/libpanic_unwind/lib.rs index 60ddf70cea52f..ad82f22510c41 100644 --- a/src/libpanic_unwind/lib.rs +++ b/src/libpanic_unwind/lib.rs @@ -32,6 +32,7 @@ #![feature(panic_runtime)] use alloc::boxed::Box; +use core::any::Any; use core::panic::BoxMeUp; // If adding to this list, you should also look at libstd::panicking's identical @@ -70,10 +71,10 @@ extern "C" { mod dwarf; #[no_mangle] -pub unsafe extern "C" fn __rust_panic_cleanup(payload: *mut u8) -> core::raw::TraitObject { +pub unsafe extern "C" fn __rust_panic_cleanup(payload: *mut u8) -> *mut (dyn Any + Send + 'static) { let payload = payload as *mut imp::Payload; let payload = *(payload); - core::mem::transmute(imp::cleanup(payload)) + Box::into_raw(imp::cleanup(payload)) } // Entry point for raising an exception, just delegates to the platform-specific diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs index 3dd1f09e07656..b02cedd5da5bf 100644 --- a/src/libstd/panicking.rs +++ b/src/libstd/panicking.rs @@ -67,7 +67,7 @@ cfg_if::cfg_if! { extern "C" { /// The payload ptr here is actually the same as the payload ptr for the try /// intrinsic (i.e., is really `*mut [u64; 2]` or `*mut *mut u8`). - fn __rust_panic_cleanup(payload: *mut u8) -> core::raw::TraitObject; + fn __rust_panic_cleanup(payload: *mut u8) -> *mut (dyn Any + Send + 'static); /// `payload` is actually a `*mut &mut dyn BoxMeUp` but that would cause FFI warnings. /// It cannot be `Box` because the other end of this call does not depend @@ -313,7 +313,7 @@ pub unsafe fn r#try R>(f: F) -> Result> // non-cold function, though, as of the writing of this comment). #[cold] unsafe fn cleanup(mut payload: Payload) -> Box { - let obj = crate::mem::transmute(__rust_panic_cleanup(&mut payload as *mut _ as *mut u8)); + let obj = Box::from_raw(__rust_panic_cleanup(&mut payload as *mut _ as *mut u8)); update_panic_count(-1); obj } From 39aa3058511d85a756fe0deef59bca6ace71bfa5 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Sun, 29 Dec 2019 12:07:44 +0100 Subject: [PATCH 07/20] Ignore broken no-landing-pads test --- src/test/ui/no-landing-pads.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/ui/no-landing-pads.rs b/src/test/ui/no-landing-pads.rs index d9d532106125a..44af25f7f8f48 100644 --- a/src/test/ui/no-landing-pads.rs +++ b/src/test/ui/no-landing-pads.rs @@ -1,6 +1,7 @@ // run-pass // compile-flags: -Z no-landing-pads -C codegen-units=1 // ignore-emscripten no threads support +// ignore-test fails because catch_unwind doesn't work with no-landing-pads use std::thread; From b3a07b197b28742166cbe3b72284f77d284d571a Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Tue, 7 Jan 2020 16:41:59 +0100 Subject: [PATCH 08/20] Apply review feedback --- Cargo.lock | 1 + src/libpanic_abort/Cargo.toml | 1 + src/libpanic_abort/lib.rs | 5 ++++- src/libpanic_unwind/dummy.rs | 2 -- src/libpanic_unwind/emcc.rs | 2 -- src/libpanic_unwind/gcc.rs | 2 -- src/libpanic_unwind/hermit.rs | 2 -- src/libpanic_unwind/lib.rs | 12 +++++++----- src/libpanic_unwind/payload.rs | 21 +++++++++++++++++++++ src/libpanic_unwind/seh.rs | 2 -- src/libstd/panicking.rs | 34 ++++++---------------------------- src/test/ui/no-landing-pads.rs | 24 ------------------------ 12 files changed, 40 insertions(+), 68 deletions(-) create mode 100644 src/libpanic_unwind/payload.rs delete mode 100644 src/test/ui/no-landing-pads.rs diff --git a/Cargo.lock b/Cargo.lock index beda3993353f4..6ffca04cafb7f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2308,6 +2308,7 @@ dependencies = [ name = "panic_abort" version = "0.0.0" dependencies = [ + "cfg-if", "compiler_builtins", "core", "libc", diff --git a/src/libpanic_abort/Cargo.toml b/src/libpanic_abort/Cargo.toml index 2bee0b716c750..8ebd95047ac23 100644 --- a/src/libpanic_abort/Cargo.toml +++ b/src/libpanic_abort/Cargo.toml @@ -14,3 +14,4 @@ doc = false core = { path = "../libcore" } libc = { version = "0.2", default-features = false } compiler_builtins = "0.1.0" +cfg-if = "0.1.8" diff --git a/src/libpanic_abort/lib.rs b/src/libpanic_abort/lib.rs index fe9196ef2314b..6ea818ecef827 100644 --- a/src/libpanic_abort/lib.rs +++ b/src/libpanic_abort/lib.rs @@ -20,8 +20,11 @@ use core::any::Any; +// We need the definition of TryPayload for __rust_panic_cleanup. +include!("../libpanic_unwind/payload.rs"); + #[rustc_std_internal_symbol] -pub unsafe extern "C" fn __rust_panic_cleanup(_: *mut u8) -> *mut (dyn Any + Send + 'static) { +pub unsafe extern "C" fn __rust_panic_cleanup(_: TryPayload) -> *mut (dyn Any + Send + 'static) { unreachable!() } diff --git a/src/libpanic_unwind/dummy.rs b/src/libpanic_unwind/dummy.rs index 30593d3b88af9..4667ede2baad5 100644 --- a/src/libpanic_unwind/dummy.rs +++ b/src/libpanic_unwind/dummy.rs @@ -6,8 +6,6 @@ use alloc::boxed::Box; use core::any::Any; use core::intrinsics; -pub type Payload = *mut u8; - pub unsafe fn cleanup(_ptr: *mut u8) -> Box { intrinsics::abort() } diff --git a/src/libpanic_unwind/emcc.rs b/src/libpanic_unwind/emcc.rs index 873135414bd9d..e541ec3002510 100644 --- a/src/libpanic_unwind/emcc.rs +++ b/src/libpanic_unwind/emcc.rs @@ -48,8 +48,6 @@ static EXCEPTION_TYPE_INFO: TypeInfo = TypeInfo { name: b"rust_panic\0".as_ptr(), }; -pub type Payload = *mut u8; - struct Exception { // This needs to be an Option because the object's lifetime follows C++ // semantics: when catch_unwind moves the Box out of the exception it must diff --git a/src/libpanic_unwind/gcc.rs b/src/libpanic_unwind/gcc.rs index dd84a814f48b1..20ae5edaa2a69 100644 --- a/src/libpanic_unwind/gcc.rs +++ b/src/libpanic_unwind/gcc.rs @@ -82,8 +82,6 @@ pub unsafe fn panic(data: Box) -> u32 { } } -pub type Payload = *mut u8; - pub unsafe fn cleanup(ptr: *mut u8) -> Box { let exception = Box::from_raw(ptr as *mut Exception); exception.cause diff --git a/src/libpanic_unwind/hermit.rs b/src/libpanic_unwind/hermit.rs index 8ffb4bcd3df23..6bded4dd499bd 100644 --- a/src/libpanic_unwind/hermit.rs +++ b/src/libpanic_unwind/hermit.rs @@ -6,8 +6,6 @@ use alloc::boxed::Box; use core::any::Any; use core::ptr; -pub type Payload = *mut u8; - pub unsafe fn cleanup(_ptr: *mut u8) -> Box { extern "C" { pub fn __rust_abort() -> !; diff --git a/src/libpanic_unwind/lib.rs b/src/libpanic_unwind/lib.rs index ad82f22510c41..87d24841d04a3 100644 --- a/src/libpanic_unwind/lib.rs +++ b/src/libpanic_unwind/lib.rs @@ -35,8 +35,8 @@ use alloc::boxed::Box; use core::any::Any; use core::panic::BoxMeUp; -// If adding to this list, you should also look at libstd::panicking's identical -// list of Payload types and likely add to there as well. +// If adding to this list, you should also look at the list of TryPayload types +// defined in payload.rs and likely add to there as well. cfg_if::cfg_if! { if #[cfg(target_os = "emscripten")] { #[path = "emcc.rs"] @@ -62,6 +62,8 @@ cfg_if::cfg_if! { } } +include!("payload.rs"); + extern "C" { /// Handler in libstd called when a panic object is dropped outside of /// `catch_unwind`. @@ -71,9 +73,9 @@ extern "C" { mod dwarf; #[no_mangle] -pub unsafe extern "C" fn __rust_panic_cleanup(payload: *mut u8) -> *mut (dyn Any + Send + 'static) { - let payload = payload as *mut imp::Payload; - let payload = *(payload); +pub unsafe extern "C" fn __rust_panic_cleanup( + payload: TryPayload, +) -> *mut (dyn Any + Send + 'static) { Box::into_raw(imp::cleanup(payload)) } diff --git a/src/libpanic_unwind/payload.rs b/src/libpanic_unwind/payload.rs new file mode 100644 index 0000000000000..1234db7da0f08 --- /dev/null +++ b/src/libpanic_unwind/payload.rs @@ -0,0 +1,21 @@ +// Type definition for the payload argument of the try intrinsic. +// +// This must be kept in sync with the implementations of the try intrinsic. +// +// This file is included by both panic runtimes and libstd. It is part of the +// panic runtime ABI. +cfg_if::cfg_if! { + if #[cfg(target_os = "emscripten")] { + type TryPayload = *mut u8; + } else if #[cfg(target_arch = "wasm32")] { + type TryPayload = *mut u8; + } else if #[cfg(target_os = "hermit")] { + type TryPayload = *mut u8; + } else if #[cfg(all(target_env = "msvc", target_arch = "aarch64"))] { + type TryPayload = *mut u8; + } else if #[cfg(target_env = "msvc")] { + type TryPayload = [u64; 2]; + } else { + type TryPayload = *mut u8; + } +} diff --git a/src/libpanic_unwind/seh.rs b/src/libpanic_unwind/seh.rs index 6f464c1ab680e..da5ee5369e082 100644 --- a/src/libpanic_unwind/seh.rs +++ b/src/libpanic_unwind/seh.rs @@ -308,8 +308,6 @@ pub unsafe fn panic(data: Box) -> u32 { _CxxThrowException(throw_ptr, &mut THROW_INFO as *mut _ as *mut _); } -pub type Payload = [u64; 2]; - pub unsafe fn cleanup(payload: [u64; 2]) -> Box { mem::transmute(raw::TraitObject { data: payload[0] as *mut _, vtable: payload[1] as *mut _ }) } diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs index b02cedd5da5bf..38cb4418dd036 100644 --- a/src/libstd/panicking.rs +++ b/src/libstd/panicking.rs @@ -28,30 +28,8 @@ use crate::io::set_panic; #[cfg(test)] use realstd::io::set_panic; -// This must be kept in sync with the implementations in libpanic_unwind. -// -// This is *not* checked in anyway; the compiler does not allow us to use a -// type/macro/anything from panic_unwind, since we're then linking in the -// panic_unwind runtime even during -Cpanic=abort. -// -// Essentially this must be the type of `imp::Payload` in libpanic_unwind. -cfg_if::cfg_if! { - if #[cfg(not(feature = "panic_unwind"))] { - type Payload = (); - } else if #[cfg(target_os = "emscripten")] { - type Payload = *mut u8; - } else if #[cfg(target_arch = "wasm32")] { - type Payload = *mut u8; - } else if #[cfg(target_os = "hermit")] { - type Payload = *mut u8; - } else if #[cfg(all(target_env = "msvc", target_arch = "aarch64"))] { - type Payload = *mut u8; - } else if #[cfg(target_env = "msvc")] { - type Payload = [u64; 2]; - } else { - type Payload = *mut u8; - } -} +// Include the definition of UnwindPayload from libpanic_unwind. +include!("../libpanic_unwind/payload.rs"); // Binary interface to the panic runtime that the standard library depends on. // @@ -67,7 +45,7 @@ cfg_if::cfg_if! { extern "C" { /// The payload ptr here is actually the same as the payload ptr for the try /// intrinsic (i.e., is really `*mut [u64; 2]` or `*mut *mut u8`). - fn __rust_panic_cleanup(payload: *mut u8) -> *mut (dyn Any + Send + 'static); + fn __rust_panic_cleanup(payload: TryPayload) -> *mut (dyn Any + Send + 'static); /// `payload` is actually a `*mut &mut dyn BoxMeUp` but that would cause FFI warnings. /// It cannot be `Box` because the other end of this call does not depend @@ -297,7 +275,7 @@ pub unsafe fn r#try R>(f: F) -> Result> // method of calling a catch panic whilst juggling ownership. let mut data = Data { f: ManuallyDrop::new(f) }; - let mut payload: MaybeUninit = MaybeUninit::uninit(); + let mut payload: MaybeUninit = MaybeUninit::uninit(); let data_ptr = &mut data as *mut _ as *mut u8; let payload_ptr = payload.as_mut_ptr() as *mut _; @@ -312,8 +290,8 @@ pub unsafe fn r#try R>(f: F) -> Result> // optimizer (in most cases this function is not inlined even as a normal, // non-cold function, though, as of the writing of this comment). #[cold] - unsafe fn cleanup(mut payload: Payload) -> Box { - let obj = Box::from_raw(__rust_panic_cleanup(&mut payload as *mut _ as *mut u8)); + unsafe fn cleanup(payload: TryPayload) -> Box { + let obj = Box::from_raw(__rust_panic_cleanup(payload)); update_panic_count(-1); obj } diff --git a/src/test/ui/no-landing-pads.rs b/src/test/ui/no-landing-pads.rs deleted file mode 100644 index 44af25f7f8f48..0000000000000 --- a/src/test/ui/no-landing-pads.rs +++ /dev/null @@ -1,24 +0,0 @@ -// run-pass -// compile-flags: -Z no-landing-pads -C codegen-units=1 -// ignore-emscripten no threads support -// ignore-test fails because catch_unwind doesn't work with no-landing-pads - -use std::thread; - -static mut HIT: bool = false; - -struct A; - -impl Drop for A { - fn drop(&mut self) { - unsafe { HIT = true; } - } -} - -fn main() { - thread::spawn(move|| -> () { - let _a = A; - panic!(); - }).join().unwrap_err(); - assert!(unsafe { !HIT }); -} From bf2c05aaea2c7453f710ad47d55aaeb9ec32cddf Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Mon, 13 Jan 2020 00:55:36 +0000 Subject: [PATCH 09/20] Fix cross-DLL panics under MSVC --- .../src/language-features/lang-items.md | 1 - src/libpanic_unwind/seh.rs | 13 ++++---- src/librustc_codegen_llvm/intrinsic.rs | 30 +++++++++++++++---- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/doc/unstable-book/src/language-features/lang-items.md b/src/doc/unstable-book/src/language-features/lang-items.md index 6f096e582f575..b6e61e7050cea 100644 --- a/src/doc/unstable-book/src/language-features/lang-items.md +++ b/src/doc/unstable-book/src/language-features/lang-items.md @@ -248,7 +248,6 @@ the source code. - `eh_personality`: `libpanic_unwind/gcc.rs` (GNU) - `eh_personality`: `libpanic_unwind/seh.rs` (SEH) - `eh_unwind_resume`: `libpanic_unwind/gcc.rs` (GCC) - - `eh_catch_typeinfo`: `libpanic_unwind/seh.rs` (SEH) - `eh_catch_typeinfo`: `libpanic_unwind/emcc.rs` (EMCC) - `panic`: `libcore/panicking.rs` - `panic_bounds_check`: `libcore/panicking.rs` diff --git a/src/libpanic_unwind/seh.rs b/src/libpanic_unwind/seh.rs index da5ee5369e082..f599f9815a62c 100644 --- a/src/libpanic_unwind/seh.rs +++ b/src/libpanic_unwind/seh.rs @@ -167,6 +167,9 @@ pub struct _TypeDescriptor { // Note that we intentionally ignore name mangling rules here: we don't want C++ // to be able to catch Rust panics by simply declaring a `struct rust_panic`. +// +// When modifying, make sure that the type name string exactly matches +// the one used in src/librustc_codegen_llvm/intrinsic.rs. const TYPE_NAME: [u8; 11] = *b"rust_panic\0"; static mut THROW_INFO: _ThrowInfo = _ThrowInfo { @@ -199,12 +202,12 @@ extern "C" { static TYPE_INFO_VTABLE: *const u8; } -// We use #[lang = "eh_catch_typeinfo"] here as this is the type descriptor which -// we'll use in LLVM's `catchpad` instruction which ends up also being passed as -// an argument to the C++ personality function. +// This type descriptor is only used when throwing an exception. The catch part +// is handled by the try intrinsic, which generates its own TypeDescriptor. // -// Again, I'm not entirely sure what this is describing, it just seems to work. -#[cfg_attr(not(test), lang = "eh_catch_typeinfo")] +// This is fine since the MSVC runtime uses string comparison on the type name +// to match TypeDescriptors rather than pointer equality. +#[cfg_attr(bootstrap, lang = "eh_catch_typeinfo")] static mut TYPE_DESCRIPTOR: _TypeDescriptor = _TypeDescriptor { pVFTable: unsafe { &TYPE_INFO_VTABLE } as *const _ as *const _, spare: core::ptr::null_mut(), diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 32f0154fa50bf..d147a40d6679f 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -954,6 +954,31 @@ fn codegen_msvc_try( let cs = catchswitch.catch_switch(None, None, 1); catchswitch.add_handler(cs, catchpad.llbb()); + // We can't use the TypeDescriptor defined in libpanic_unwind because it + // might be in another DLL and the SEH encoding only supports specifying + // a TypeDescriptor from the current module. + // + // However this isn't an issue since the MSVC runtime uses string + // comparison on the type name to match TypeDescriptors rather than + // pointer equality. + // + // So instead we generate a new TypeDescriptor in each module that uses + // `try` and let the linker merge duplicate definitions in the same + // module. + // + // When modifying, make sure that the type_name string exactly matches + // the one used in src/libpanic_unwind/seh.rs. + let type_info_vtable = bx.declare_global("??_7type_info@@6B@", bx.type_i8p()); + let type_name = bx.const_bytes(b"rust_panic\0"); + let type_info = + bx.const_struct(&[type_info_vtable, bx.const_null(bx.type_i8p()), type_name], false); + let tydesc = bx.declare_global("__rust_panic_type_info", bx.val_ty(type_info)); + unsafe { + llvm::LLVMRustSetLinkage(tydesc, llvm::Linkage::LinkOnceODRLinkage); + llvm::SetUniqueComdat(bx.llmod, tydesc); + llvm::LLVMSetInitializer(tydesc, type_info); + } + // The flag value of 8 indicates that we are catching the exception by // reference instead of by value. We can't use catch by value because // that requires copying the exception object, which we don't support @@ -961,12 +986,7 @@ fn codegen_msvc_try( // // Source: MicrosoftCXXABI::getAddrOfCXXCatchHandlerType in clang let flags = bx.const_i32(8); - let tydesc = match bx.tcx().lang_items().eh_catch_typeinfo() { - Some(did) => bx.get_static(did), - None => bug!("eh_catch_typeinfo not defined, but needed for SEH unwinding"), - }; let funclet = catchpad.catch_pad(cs, &[tydesc, flags, slot]); - let i64_align = bx.tcx().data_layout.i64_align.abi; let payload_ptr = catchpad.load(slot, ptr_align); let payload = catchpad.load(payload_ptr, i64_align); From a3731a24816f8ce0c4011d20a20ef01bb28d33f5 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Tue, 14 Jan 2020 17:42:47 +0000 Subject: [PATCH 10/20] Apply CPU attributes to __rust_try --- src/librustc_codegen_llvm/intrinsic.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index d147a40d6679f..8b9a96294ced1 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -1106,6 +1106,8 @@ fn gen_fn<'ll, 'tcx>( )); let fn_abi = FnAbi::of_fn_ptr(cx, rust_fn_sig, &[]); let llfn = cx.declare_fn(name, &fn_abi); + cx.set_frame_pointer_elimination(llfn); + cx.apply_target_cpu_attr(llfn); // FIXME(eddyb) find a nicer way to do this. unsafe { llvm::LLVMRustSetLinkage(llfn, llvm::Linkage::InternalLinkage) }; let bx = Builder::new_block(cx, llfn, "entry-block"); From 537ca394787be2a2ac3eb85d5d823cdb5d2a17b6 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Wed, 22 Jan 2020 18:03:59 -0500 Subject: [PATCH 11/20] [DO NOT MERGE] enable mingw builder on try --- src/ci/azure-pipelines/try.yml | 34 ++++++++++++---------------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/src/ci/azure-pipelines/try.yml b/src/ci/azure-pipelines/try.yml index f8ddf0eb46cfd..1a1e963bc9a5a 100644 --- a/src/ci/azure-pipelines/try.yml +++ b/src/ci/azure-pipelines/try.yml @@ -49,25 +49,15 @@ jobs: # NO_LLVM_ASSERTIONS: 1 # NO_DEBUG_ASSERTIONS: 1 # -# - job: Windows -# timeoutInMinutes: 600 -# pool: -# vmImage: 'vs2017-win2016' -# steps: -# - template: steps/run.yml -# strategy: -# matrix: -# dist-x86_64-msvc: -# RUST_CONFIGURE_ARGS: > -# --build=x86_64-pc-windows-msvc -# --target=x86_64-pc-windows-msvc,aarch64-pc-windows-msvc -# --enable-full-tools -# --enable-profiler -# SCRIPT: python x.py dist -# DIST_REQUIRE_ALL_TOOLS: 1 -# DEPLOY: 1 -# -# dist-x86_64-msvc-alt: -# RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-extended --enable-profiler -# SCRIPT: python x.py dist -# DEPLOY_ALT: 1 +- job: Windows + timeoutInMinutes: 600 + pool: + vmImage: 'vs2017-win2016' + steps: + - template: steps/run.yml + strategy: + matrix: + i686-mingw-2: + RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu + SCRIPT: make ci-mingw-subset-2 + CUSTOM_MINGW: 1 From a67775510a7d338600b596c2fd911b7207f226a5 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Fri, 24 Jan 2020 09:21:05 -0500 Subject: [PATCH 12/20] Also distribute mingw --- src/ci/azure-pipelines/try.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/ci/azure-pipelines/try.yml b/src/ci/azure-pipelines/try.yml index 1a1e963bc9a5a..e0199c1409e06 100644 --- a/src/ci/azure-pipelines/try.yml +++ b/src/ci/azure-pipelines/try.yml @@ -61,3 +61,8 @@ jobs: RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu SCRIPT: make ci-mingw-subset-2 CUSTOM_MINGW: 1 + dist-i686-mingw: + RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu --enable-full-tools --enable-profiler + SCRIPT: python x.py dist + CUSTOM_MINGW: 1 + DIST_REQUIRE_ALL_TOOLS: 1 From a66a223a60bbc4813239d6a56344fef409094fb1 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sat, 25 Jan 2020 09:49:29 -0500 Subject: [PATCH 13/20] Enable debug information --- src/ci/azure-pipelines/try.yml | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/ci/azure-pipelines/try.yml b/src/ci/azure-pipelines/try.yml index e0199c1409e06..2452f80884c74 100644 --- a/src/ci/azure-pipelines/try.yml +++ b/src/ci/azure-pipelines/try.yml @@ -6,17 +6,17 @@ variables: - group: prod-credentials jobs: -- job: Linux - timeoutInMinutes: 600 - pool: - vmImage: ubuntu-16.04 - steps: - - template: steps/run.yml - strategy: - matrix: - dist-x86_64-linux: {} - dist-x86_64-linux-alt: - IMAGE: dist-x86_64-linux + # - job: Linux + # timeoutInMinutes: 600 + # pool: + # vmImage: ubuntu-16.04 + # steps: + # - template: steps/run.yml + # strategy: + # matrix: + # dist-x86_64-linux: {} + # dist-x86_64-linux-alt: + # IMAGE: dist-x86_64-linux # The macOS and Windows builds here are currently disabled due to them not being # overly necessary on `try` builds. We also don't actually have anything that @@ -62,7 +62,7 @@ jobs: SCRIPT: make ci-mingw-subset-2 CUSTOM_MINGW: 1 dist-i686-mingw: - RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu --enable-full-tools --enable-profiler + RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu --enable-debug-assertions --enable-optimize --debuginfo-level=1 SCRIPT: python x.py dist CUSTOM_MINGW: 1 - DIST_REQUIRE_ALL_TOOLS: 1 + N_DIST_REQUIRE_ALL_TOOLS: 1 From 105b88227f96193c276747f141ee2e932cdf9c13 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Mon, 27 Jan 2020 06:10:10 +0000 Subject: [PATCH 14/20] Implement rust_eh_unwind_resume as a naked function --- src/libpanic_unwind/gcc.rs | 9 +++++++-- src/libpanic_unwind/lib.rs | 2 ++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/libpanic_unwind/gcc.rs b/src/libpanic_unwind/gcc.rs index 20ae5edaa2a69..214e1fc98e785 100644 --- a/src/libpanic_unwind/gcc.rs +++ b/src/libpanic_unwind/gcc.rs @@ -332,8 +332,13 @@ unsafe fn find_eh_action( ))] #[lang = "eh_unwind_resume"] #[unwind(allowed)] -unsafe extern "C" fn rust_eh_unwind_resume(panic_ctx: *mut u8) -> ! { - uw::_Unwind_Resume(panic_ctx as *mut uw::_Unwind_Exception); +#[naked] +unsafe extern "C" fn rust_eh_unwind_resume(_panic_ctx: *mut u8) -> ! { + // This needs to be a naked function because _Unwind_Resume expects to be + // called directly from the landing pad. This means that we need to force + // a tail call here. + asm!("jmp ${0:P}" :: "s" (uw::_Unwind_Resume as usize) :: "volatile"); + core::hint::unreachable_unchecked(); } // Frame unwind info registration diff --git a/src/libpanic_unwind/lib.rs b/src/libpanic_unwind/lib.rs index 87d24841d04a3..14f29f2697279 100644 --- a/src/libpanic_unwind/lib.rs +++ b/src/libpanic_unwind/lib.rs @@ -28,6 +28,8 @@ #![feature(abi_thiscall)] #![feature(rustc_attrs)] #![feature(raw)] +#![feature(asm)] +#![feature(naked_functions)] #![panic_runtime] #![feature(panic_runtime)] From 7aeb3911b40e37d95d90be19ff8b50f7775671dd Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Tue, 28 Jan 2020 12:30:57 +0000 Subject: [PATCH 15/20] Mark rust_eh_unwind_resume as #[inline(never)] for stage0 --- src/libpanic_unwind/gcc.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libpanic_unwind/gcc.rs b/src/libpanic_unwind/gcc.rs index 214e1fc98e785..290ced470e61d 100644 --- a/src/libpanic_unwind/gcc.rs +++ b/src/libpanic_unwind/gcc.rs @@ -333,6 +333,7 @@ unsafe fn find_eh_action( #[lang = "eh_unwind_resume"] #[unwind(allowed)] #[naked] +#[inline(never)] unsafe extern "C" fn rust_eh_unwind_resume(_panic_ctx: *mut u8) -> ! { // This needs to be a naked function because _Unwind_Resume expects to be // called directly from the landing pad. This means that we need to force From 7aac2c3cf966e8359876aee47a81534dddeebd04 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Fri, 28 Feb 2020 18:57:19 +0000 Subject: [PATCH 16/20] Use hacked llvm which uses rust_eh_unwind_resume instead of _Unwind_Resume --- .gitmodules | 4 ++-- src/llvm-project | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitmodules b/.gitmodules index 003e50d0788e4..aa24426e13538 100644 --- a/.gitmodules +++ b/.gitmodules @@ -39,8 +39,8 @@ url = https://github.com/rust-lang/edition-guide.git [submodule "src/llvm-project"] path = src/llvm-project - url = https://github.com/rust-lang/llvm-project.git - branch = rustc/9.0-2019-12-19 + url = https://github.com/Amanieu/llvm-project.git + branch = opt-catch [submodule "src/doc/embedded-book"] path = src/doc/embedded-book url = https://github.com/rust-embedded/book.git diff --git a/src/llvm-project b/src/llvm-project index 9f65ad057357b..dd3864293a5ba 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit 9f65ad057357b307180955831968f79e74090a90 +Subproject commit dd3864293a5ba9123ee12983018ffafac9d16c78 From 22dcdbad417e3494f3030ad9af7cebe91a1208cc Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Fri, 28 Feb 2020 18:58:50 +0000 Subject: [PATCH 17/20] Disable custom_unwind_resume on Windows --- src/librustc_target/spec/windows_base.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_target/spec/windows_base.rs b/src/librustc_target/spec/windows_base.rs index 693a343d5a5fb..98449ccb85e5e 100644 --- a/src/librustc_target/spec/windows_base.rs +++ b/src/librustc_target/spec/windows_base.rs @@ -64,7 +64,7 @@ pub fn opts() -> TargetOptions { ], late_link_args, post_link_objects: vec!["rsend.o".to_string()], - custom_unwind_resume: true, + custom_unwind_resume: false, abi_return_struct_as_int: true, emit_debug_gdb_scripts: false, requires_uwtable: true, From f531f3ba7aec87ac5b0e4f2f6e0b66790b58cd21 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Fri, 28 Feb 2020 23:13:36 +0000 Subject: [PATCH 18/20] Use a global_asm! instead of a naked function --- src/libpanic_unwind/gcc.rs | 32 ++++++++++++++++++++++++-------- src/libpanic_unwind/lib.rs | 1 + 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/libpanic_unwind/gcc.rs b/src/libpanic_unwind/gcc.rs index 290ced470e61d..6cea4907a3fb5 100644 --- a/src/libpanic_unwind/gcc.rs +++ b/src/libpanic_unwind/gcc.rs @@ -326,22 +326,38 @@ unsafe fn find_eh_action( // See docs in the `unwind` module. #[cfg(all( + not(bootstrap), + target_os = "windows", + any(target_arch = "x86", target_arch = "x86_64"), + target_env = "gnu" +))] +global_asm! { + r#" + .def _rust_eh_unwind_resume; + .scl 2; + .type 32; + .endef + .globl _rust_eh_unwind_resume + .p2align 4, 0x90 +_rust_eh_unwind_resume: + .cfi_startproc + jmp __Unwind_Resume + .cfi_endproc + "# +} +#[cfg(all( + bootstrap, target_os = "windows", any(target_arch = "x86", target_arch = "x86_64"), target_env = "gnu" ))] #[lang = "eh_unwind_resume"] #[unwind(allowed)] -#[naked] -#[inline(never)] -unsafe extern "C" fn rust_eh_unwind_resume(_panic_ctx: *mut u8) -> ! { - // This needs to be a naked function because _Unwind_Resume expects to be - // called directly from the landing pad. This means that we need to force - // a tail call here. - asm!("jmp ${0:P}" :: "s" (uw::_Unwind_Resume as usize) :: "volatile"); - core::hint::unreachable_unchecked(); +unsafe extern "C" fn rust_eh_unwind_resume(panic_ctx: *mut u8) -> ! { + uw::_Unwind_Resume(panic_ctx as *mut uw::_Unwind_Exception); } + // Frame unwind info registration // // Each module's image contains a frame unwind info section (usually diff --git a/src/libpanic_unwind/lib.rs b/src/libpanic_unwind/lib.rs index 14f29f2697279..686282f966460 100644 --- a/src/libpanic_unwind/lib.rs +++ b/src/libpanic_unwind/lib.rs @@ -32,6 +32,7 @@ #![feature(naked_functions)] #![panic_runtime] #![feature(panic_runtime)] +#![feature(global_asm)] use alloc::boxed::Box; use core::any::Any; From 708a24691144cecc70582b7cd7dd01f715043300 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Sat, 29 Feb 2020 09:44:17 +0000 Subject: [PATCH 19/20] Export rust_eh_unwind_resume symbol --- src/librustc_codegen_ssa/back/symbol_export.rs | 6 ++++++ src/librustc_codegen_ssa/mir/block.rs | 13 ++++--------- src/librustc_target/spec/windows_base.rs | 2 +- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs index a6cd0c09684dd..8f8ae70267ff6 100644 --- a/src/librustc_codegen_ssa/back/symbol_export.rs +++ b/src/librustc_codegen_ssa/back/symbol_export.rs @@ -182,6 +182,12 @@ fn exported_symbols_provider_local( symbols.push((exported_symbol, SymbolExportLevel::C)); } + if tcx.is_panic_runtime(LOCAL_CRATE) && tcx.sess.target.target.options.custom_unwind_resume { + let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new("rust_eh_unwind_resume")); + + symbols.push((exported_symbol, SymbolExportLevel::Rust)); + } + if tcx.allocator_kind().is_some() { for method in ALLOCATOR_METHODS { let symbol_name = format!("__rust_{}", method.name); diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index a1b54607b809e..2cf0cceb91039 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -178,15 +178,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let lp1 = bx.load_operand(lp1).immediate(); slot.storage_dead(&mut bx); - if !bx.sess().target.target.options.custom_unwind_resume { - let mut lp = bx.const_undef(self.landing_pad_type()); - lp = bx.insert_value(lp, lp0, 0); - lp = bx.insert_value(lp, lp1, 1); - bx.resume(lp); - } else { - bx.call(bx.eh_unwind_resume(), &[lp0], helper.funclet(self)); - bx.unreachable(); - } + let mut lp = bx.const_undef(self.landing_pad_type()); + lp = bx.insert_value(lp, lp0, 0); + lp = bx.insert_value(lp, lp1, 1); + bx.resume(lp); } } diff --git a/src/librustc_target/spec/windows_base.rs b/src/librustc_target/spec/windows_base.rs index 98449ccb85e5e..693a343d5a5fb 100644 --- a/src/librustc_target/spec/windows_base.rs +++ b/src/librustc_target/spec/windows_base.rs @@ -64,7 +64,7 @@ pub fn opts() -> TargetOptions { ], late_link_args, post_link_objects: vec!["rsend.o".to_string()], - custom_unwind_resume: false, + custom_unwind_resume: true, abi_return_struct_as_int: true, emit_debug_gdb_scripts: false, requires_uwtable: true, From 873bc5c42b72b0a2e86ddc9e171991a5e2000d3d Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Sat, 29 Feb 2020 11:08:23 +0000 Subject: [PATCH 20/20] Remove eh_unwind_resume lang item --- .../src/language-features/lang-items.md | 21 ++------- src/librustc/middle/lang_items.rs | 3 +- src/librustc_codegen_llvm/context.rs | 47 +------------------ src/librustc_codegen_ssa/traits/misc.rs | 1 - src/librustc_hir/lang_items.rs | 1 - src/librustc_hir/weak_lang_items.rs | 1 - src/librustc_passes/weak_lang_items.rs | 3 -- src/librustc_span/symbol.rs | 2 - src/librustc_target/spec/mod.rs | 2 +- .../auxiliary/panic-runtime-lang-items.rs | 2 - .../const-eval/const_panic_libcore_main.rs | 2 - .../macros/macro-comma-behavior.core.stderr | 14 +++--- src/test/ui/macros/macro-comma-behavior.rs | 1 - .../ui/macros/macro-comma-behavior.std.stderr | 20 ++++---- src/test/ui/no_owned_box_lang_item.rs | 1 - .../auxiliary/panic-runtime-lang-items.rs | 2 - src/test/ui/range/issue-54505-no-std.rs | 4 -- src/test/ui/range/issue-54505-no-std.stderr | 12 ++--- 18 files changed, 30 insertions(+), 109 deletions(-) diff --git a/src/doc/unstable-book/src/language-features/lang-items.md b/src/doc/unstable-book/src/language-features/lang-items.md index b6e61e7050cea..d65dc1b61f03f 100644 --- a/src/doc/unstable-book/src/language-features/lang-items.md +++ b/src/doc/unstable-book/src/language-features/lang-items.md @@ -52,7 +52,6 @@ fn main(_argc: isize, _argv: *const *const u8) -> isize { #[lang = "eh_personality"] extern fn rust_eh_personality() {} #[lang = "panic_impl"] extern fn rust_begin_panic(info: &PanicInfo) -> ! { unsafe { intrinsics::abort() } } -#[lang = "eh_unwind_resume"] extern fn rust_eh_unwind_resume() {} #[no_mangle] pub extern fn rust_eh_register_frames () {} #[no_mangle] pub extern fn rust_eh_unregister_frames () {} ``` @@ -67,7 +66,7 @@ Other features provided by lang items include: marked with lang items; those specific four are `eq`, `ord`, `deref`, and `add` respectively. - stack unwinding and general failure; the `eh_personality`, - `eh_unwind_resume`, `fail` and `fail_bounds_checks` lang items. + `fail` and `fail_bounds_checks` lang items. - the traits in `std::marker` used to indicate types of various kinds; lang items `send`, `sync` and `copy`. - the marker types and variance indicators found in @@ -130,12 +129,6 @@ fn start(_argc: isize, _argv: *const *const u8) -> isize { pub extern fn rust_eh_personality() { } -// This function may be needed based on the compilation target. -#[lang = "eh_unwind_resume"] -#[no_mangle] -pub extern fn rust_eh_unwind_resume() { -} - #[lang = "panic_impl"] #[no_mangle] pub extern fn rust_begin_panic(info: &PanicInfo) -> ! { @@ -173,12 +166,6 @@ pub extern fn main(_argc: i32, _argv: *const *const u8) -> i32 { pub extern fn rust_eh_personality() { } -// This function may be needed based on the compilation target. -#[lang = "eh_unwind_resume"] -#[no_mangle] -pub extern fn rust_eh_unwind_resume() { -} - #[lang = "panic_impl"] #[no_mangle] pub extern fn rust_begin_panic(info: &PanicInfo) -> ! { @@ -213,8 +200,8 @@ the screen. While the language item's name is `panic_impl`, the symbol name is A third function, `rust_eh_unwind_resume`, is also needed if the `custom_unwind_resume` flag is set in the options of the compilation target. It allows customizing the -process of resuming unwind at the end of the landing pads. The language item's name -is `eh_unwind_resume`. +process of resuming unwind at the end of the landing pads. Since this function +must be defined in assembly code it does not have an associated language item. ## List of all language items @@ -247,8 +234,8 @@ the source code. - `eh_personality`: `libpanic_unwind/emcc.rs` (EMCC) - `eh_personality`: `libpanic_unwind/gcc.rs` (GNU) - `eh_personality`: `libpanic_unwind/seh.rs` (SEH) - - `eh_unwind_resume`: `libpanic_unwind/gcc.rs` (GCC) - `eh_catch_typeinfo`: `libpanic_unwind/emcc.rs` (EMCC) + - `rust_eh_unwind_resume`: `libpanic_unwind/gcc.rs` (GCC) - `panic`: `libcore/panicking.rs` - `panic_bounds_check`: `libcore/panicking.rs` - `panic_impl`: `libcore/panicking.rs` diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index c8e284be6fc09..36560371587a5 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -57,8 +57,7 @@ pub fn whitelisted(tcx: TyCtxt<'_>, lang_item: LangItem) -> bool { // symbols. Other panic runtimes ensure that the relevant symbols are // available to link things together, but they're never exercised. if tcx.sess.panic_strategy() != PanicStrategy::Unwind { - return lang_item == LangItem::EhPersonalityLangItem - || lang_item == LangItem::EhUnwindResumeLangItem; + return lang_item == LangItem::EhPersonalityLangItem; } false diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs index 46f461b98c8de..04e161d6e08eb 100644 --- a/src/librustc_codegen_llvm/context.rs +++ b/src/librustc_codegen_llvm/context.rs @@ -1,4 +1,3 @@ -use crate::abi::FnAbi; use crate::attributes; use crate::debuginfo; use crate::llvm; @@ -15,7 +14,7 @@ use rustc::mir::mono::CodegenUnit; use rustc::session::config::{self, CFGuard, DebugInfo}; use rustc::session::Session; use rustc::ty::layout::{ - FnAbiExt, HasParamEnv, LayoutError, LayoutOf, PointeeInfo, Size, TyLayout, VariantIdx, + HasParamEnv, LayoutError, LayoutOf, PointeeInfo, Size, TyLayout, VariantIdx, }; use rustc::ty::{self, Instance, Ty, TyCtxt}; use rustc_codegen_ssa::base::wants_msvc_seh; @@ -23,15 +22,12 @@ use rustc_data_structures::base_n; use rustc_data_structures::const_cstr; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::small_c_str::SmallCStr; -use rustc_hir::Unsafety; use rustc_target::spec::{HasTargetSpec, Target}; -use crate::abi::Abi; use rustc_span::source_map::{Span, DUMMY_SP}; use rustc_span::symbol::Symbol; use std::cell::{Cell, RefCell}; use std::ffi::CStr; -use std::iter; use std::str; use std::sync::Arc; @@ -87,7 +83,6 @@ pub struct CodegenCx<'ll, 'tcx> { pub dbg_cx: Option>, eh_personality: Cell>, - eh_unwind_resume: Cell>, pub rust_try_fn: Cell>, intrinsics: RefCell>, @@ -328,7 +323,6 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { isize_ty, dbg_cx, eh_personality: Cell::new(None), - eh_unwind_resume: Cell::new(None), rust_try_fn: Cell::new(None), intrinsics: Default::default(), local_gen_sym_counter: Cell::new(0), @@ -406,45 +400,6 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> { llfn } - // Returns a Value of the "eh_unwind_resume" lang item if one is defined, - // otherwise declares it as an external function. - fn eh_unwind_resume(&self) -> &'ll Value { - let unwresume = &self.eh_unwind_resume; - if let Some(llfn) = unwresume.get() { - return llfn; - } - - let tcx = self.tcx; - assert!(self.sess().target.target.options.custom_unwind_resume); - if let Some(def_id) = tcx.lang_items().eh_unwind_resume() { - let llfn = self.get_fn_addr( - ty::Instance::resolve( - tcx, - ty::ParamEnv::reveal_all(), - def_id, - tcx.intern_substs(&[]), - ) - .unwrap(), - ); - unwresume.set(Some(llfn)); - return llfn; - } - - let sig = ty::Binder::bind(tcx.mk_fn_sig( - iter::once(tcx.mk_mut_ptr(tcx.types.u8)), - tcx.types.never, - false, - Unsafety::Unsafe, - Abi::C, - )); - - let fn_abi = FnAbi::of_fn_ptr(self, sig, &[]); - let llfn = self.declare_fn("rust_eh_unwind_resume", &fn_abi); - attributes::apply_target_cpu_attr(self, llfn); - unwresume.set(Some(llfn)); - llfn - } - fn sess(&self) -> &Session { &self.tcx.sess } diff --git a/src/librustc_codegen_ssa/traits/misc.rs b/src/librustc_codegen_ssa/traits/misc.rs index 691b94c2f9d48..d7587163ba001 100644 --- a/src/librustc_codegen_ssa/traits/misc.rs +++ b/src/librustc_codegen_ssa/traits/misc.rs @@ -14,7 +14,6 @@ pub trait MiscMethods<'tcx>: BackendTypes { fn get_fn(&self, instance: Instance<'tcx>) -> Self::Function; fn get_fn_addr(&self, instance: Instance<'tcx>) -> Self::Value; fn eh_personality(&self) -> Self::Value; - fn eh_unwind_resume(&self) -> Self::Value; fn sess(&self) -> &Session; fn codegen_unit(&self) -> &Arc>; fn used_statics(&self) -> &RefCell>; diff --git a/src/librustc_hir/lang_items.rs b/src/librustc_hir/lang_items.rs index cb5ebba463394..9651e7b281db7 100644 --- a/src/librustc_hir/lang_items.rs +++ b/src/librustc_hir/lang_items.rs @@ -240,7 +240,6 @@ language_item_table! { StartFnLangItem, "start", start_fn, Target::Fn; EhPersonalityLangItem, "eh_personality", eh_personality, Target::Fn; - EhUnwindResumeLangItem, "eh_unwind_resume", eh_unwind_resume, Target::Fn; EhCatchTypeinfoLangItem, "eh_catch_typeinfo", eh_catch_typeinfo, Target::Static; OwnedBoxLangItem, "owned_box", owned_box, Target::Struct; diff --git a/src/librustc_hir/weak_lang_items.rs b/src/librustc_hir/weak_lang_items.rs index 79182caae8c80..933eb69054a29 100644 --- a/src/librustc_hir/weak_lang_items.rs +++ b/src/librustc_hir/weak_lang_items.rs @@ -43,6 +43,5 @@ impl LanguageItems { weak_lang_items! { panic_impl, PanicImplLangItem, rust_begin_unwind; eh_personality, EhPersonalityLangItem, rust_eh_personality; - eh_unwind_resume, EhUnwindResumeLangItem, rust_eh_unwind_resume; oom, OomLangItem, rust_oom; } diff --git a/src/librustc_passes/weak_lang_items.rs b/src/librustc_passes/weak_lang_items.rs index 010712c28ba75..88f8b8030d7e6 100644 --- a/src/librustc_passes/weak_lang_items.rs +++ b/src/librustc_passes/weak_lang_items.rs @@ -28,9 +28,6 @@ pub fn check_crate<'tcx>(tcx: TyCtxt<'tcx>, items: &mut lang_items::LanguageItem if items.eh_personality().is_none() { items.missing.push(lang_items::EhPersonalityLangItem); } - if tcx.sess.target.target.options.custom_unwind_resume & items.eh_unwind_resume().is_none() { - items.missing.push(lang_items::EhUnwindResumeLangItem); - } { let mut cx = Context { tcx, items }; diff --git a/src/librustc_span/symbol.rs b/src/librustc_span/symbol.rs index d6232f32f4c1b..6231489dfb221 100644 --- a/src/librustc_span/symbol.rs +++ b/src/librustc_span/symbol.rs @@ -287,7 +287,6 @@ symbols! { dylib, dyn_trait, eh_personality, - eh_unwind_resume, enable, Encodable, env, @@ -663,7 +662,6 @@ symbols! { rustc_variance, rustfmt, rust_eh_personality, - rust_eh_unwind_resume, rust_oom, rvalue_static_promotion, sanitize, diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index 67f45d3d230ef..65021d863bcc7 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -695,7 +695,7 @@ pub struct TargetOptions { /// Whether the target uses a custom unwind resumption routine. /// By default LLVM lowers `resume` instructions into calls to `_Unwind_Resume` /// defined in libgcc. If this option is enabled, the target must provide - /// `eh_unwind_resume` lang item. + /// a `rust_eh_unwind_resume` symbol. pub custom_unwind_resume: bool, /// Whether the runtime startup code requires the `main` function be passed /// `argc` and `argv` values. diff --git a/src/test/compile-fail/auxiliary/panic-runtime-lang-items.rs b/src/test/compile-fail/auxiliary/panic-runtime-lang-items.rs index abe34a39caf34..3e5cdad7ab936 100644 --- a/src/test/compile-fail/auxiliary/panic-runtime-lang-items.rs +++ b/src/test/compile-fail/auxiliary/panic-runtime-lang-items.rs @@ -11,5 +11,3 @@ use core::panic::PanicInfo; fn panic_impl(info: &PanicInfo) -> ! { loop {} } #[lang = "eh_personality"] fn eh_personality() {} -#[lang = "eh_unwind_resume"] -fn eh_unwind_resume() {} diff --git a/src/test/ui/consts/const-eval/const_panic_libcore_main.rs b/src/test/ui/consts/const-eval/const_panic_libcore_main.rs index 9afcdf77610f2..6b86feb5921a1 100644 --- a/src/test/ui/consts/const-eval/const_panic_libcore_main.rs +++ b/src/test/ui/consts/const-eval/const_panic_libcore_main.rs @@ -17,8 +17,6 @@ const X: () = unimplemented!(); #[lang = "eh_personality"] fn eh() {} -#[lang = "eh_unwind_resume"] -fn eh_unwind_resume() {} #[panic_handler] fn panic(_info: &PanicInfo) -> ! { diff --git a/src/test/ui/macros/macro-comma-behavior.core.stderr b/src/test/ui/macros/macro-comma-behavior.core.stderr index dd0cac659fd31..83a88ab3bd97c 100644 --- a/src/test/ui/macros/macro-comma-behavior.core.stderr +++ b/src/test/ui/macros/macro-comma-behavior.core.stderr @@ -1,41 +1,41 @@ error: 1 positional argument in format string, but no arguments were given - --> $DIR/macro-comma-behavior.rs:21:23 + --> $DIR/macro-comma-behavior.rs:20:23 | LL | assert_eq!(1, 1, "{}",); | ^^ error: 1 positional argument in format string, but no arguments were given - --> $DIR/macro-comma-behavior.rs:24:23 + --> $DIR/macro-comma-behavior.rs:23:23 | LL | assert_ne!(1, 2, "{}",); | ^^ error: 1 positional argument in format string, but no arguments were given - --> $DIR/macro-comma-behavior.rs:30:29 + --> $DIR/macro-comma-behavior.rs:29:29 | LL | debug_assert_eq!(1, 1, "{}",); | ^^ error: 1 positional argument in format string, but no arguments were given - --> $DIR/macro-comma-behavior.rs:33:29 + --> $DIR/macro-comma-behavior.rs:32:29 | LL | debug_assert_ne!(1, 2, "{}",); | ^^ error: 1 positional argument in format string, but no arguments were given - --> $DIR/macro-comma-behavior.rs:54:19 + --> $DIR/macro-comma-behavior.rs:53:19 | LL | format_args!("{}",); | ^^ error: 1 positional argument in format string, but no arguments were given - --> $DIR/macro-comma-behavior.rs:72:21 + --> $DIR/macro-comma-behavior.rs:71:21 | LL | unimplemented!("{}",); | ^^ error: 1 positional argument in format string, but no arguments were given - --> $DIR/macro-comma-behavior.rs:81:24 + --> $DIR/macro-comma-behavior.rs:80:24 | LL | write!(f, "{}",)?; | ^^ diff --git a/src/test/ui/macros/macro-comma-behavior.rs b/src/test/ui/macros/macro-comma-behavior.rs index 006319aa9f5b2..04714c65b5cb7 100644 --- a/src/test/ui/macros/macro-comma-behavior.rs +++ b/src/test/ui/macros/macro-comma-behavior.rs @@ -9,7 +9,6 @@ #[cfg(std)] use std::fmt; #[cfg(core)] use core::fmt; #[cfg(core)] #[lang = "eh_personality"] fn eh_personality() {} -#[cfg(core)] #[lang = "eh_unwind_resume"] fn eh_unwind_resume() {} #[cfg(core)] #[lang = "panic_impl"] fn panic_impl(panic: &core::panic::PanicInfo) -> ! { loop {} } // (see documentation of the similarly-named test in run-pass) diff --git a/src/test/ui/macros/macro-comma-behavior.std.stderr b/src/test/ui/macros/macro-comma-behavior.std.stderr index 4372d89fbf522..26445f2c5c542 100644 --- a/src/test/ui/macros/macro-comma-behavior.std.stderr +++ b/src/test/ui/macros/macro-comma-behavior.std.stderr @@ -1,59 +1,59 @@ error: 1 positional argument in format string, but no arguments were given - --> $DIR/macro-comma-behavior.rs:21:23 + --> $DIR/macro-comma-behavior.rs:20:23 | LL | assert_eq!(1, 1, "{}",); | ^^ error: 1 positional argument in format string, but no arguments were given - --> $DIR/macro-comma-behavior.rs:24:23 + --> $DIR/macro-comma-behavior.rs:23:23 | LL | assert_ne!(1, 2, "{}",); | ^^ error: 1 positional argument in format string, but no arguments were given - --> $DIR/macro-comma-behavior.rs:30:29 + --> $DIR/macro-comma-behavior.rs:29:29 | LL | debug_assert_eq!(1, 1, "{}",); | ^^ error: 1 positional argument in format string, but no arguments were given - --> $DIR/macro-comma-behavior.rs:33:29 + --> $DIR/macro-comma-behavior.rs:32:29 | LL | debug_assert_ne!(1, 2, "{}",); | ^^ error: 1 positional argument in format string, but no arguments were given - --> $DIR/macro-comma-behavior.rs:38:18 + --> $DIR/macro-comma-behavior.rs:37:18 | LL | eprint!("{}",); | ^^ error: 1 positional argument in format string, but no arguments were given - --> $DIR/macro-comma-behavior.rs:50:18 + --> $DIR/macro-comma-behavior.rs:49:18 | LL | format!("{}",); | ^^ error: 1 positional argument in format string, but no arguments were given - --> $DIR/macro-comma-behavior.rs:54:19 + --> $DIR/macro-comma-behavior.rs:53:19 | LL | format_args!("{}",); | ^^ error: 1 positional argument in format string, but no arguments were given - --> $DIR/macro-comma-behavior.rs:61:17 + --> $DIR/macro-comma-behavior.rs:60:17 | LL | print!("{}",); | ^^ error: 1 positional argument in format string, but no arguments were given - --> $DIR/macro-comma-behavior.rs:72:21 + --> $DIR/macro-comma-behavior.rs:71:21 | LL | unimplemented!("{}",); | ^^ error: 1 positional argument in format string, but no arguments were given - --> $DIR/macro-comma-behavior.rs:81:24 + --> $DIR/macro-comma-behavior.rs:80:24 | LL | write!(f, "{}",)?; | ^^ diff --git a/src/test/ui/no_owned_box_lang_item.rs b/src/test/ui/no_owned_box_lang_item.rs index b76699c19ac80..58e45ff73a5e6 100644 --- a/src/test/ui/no_owned_box_lang_item.rs +++ b/src/test/ui/no_owned_box_lang_item.rs @@ -12,5 +12,4 @@ fn main() { } #[lang = "eh_personality"] extern fn eh_personality() {} -#[lang = "eh_unwind_resume"] extern fn eh_unwind_resume() {} #[lang = "panic_impl"] fn panic_impl(panic: &PanicInfo) -> ! { loop {} } diff --git a/src/test/ui/panic-runtime/auxiliary/panic-runtime-lang-items.rs b/src/test/ui/panic-runtime/auxiliary/panic-runtime-lang-items.rs index abe34a39caf34..3e5cdad7ab936 100644 --- a/src/test/ui/panic-runtime/auxiliary/panic-runtime-lang-items.rs +++ b/src/test/ui/panic-runtime/auxiliary/panic-runtime-lang-items.rs @@ -11,5 +11,3 @@ use core::panic::PanicInfo; fn panic_impl(info: &PanicInfo) -> ! { loop {} } #[lang = "eh_personality"] fn eh_personality() {} -#[lang = "eh_unwind_resume"] -fn eh_unwind_resume() {} diff --git a/src/test/ui/range/issue-54505-no-std.rs b/src/test/ui/range/issue-54505-no-std.rs index 22cf15fb2e4a1..c6a3cc346fc80 100644 --- a/src/test/ui/range/issue-54505-no-std.rs +++ b/src/test/ui/range/issue-54505-no-std.rs @@ -15,10 +15,6 @@ use core::ops::RangeBounds; #[lang = "eh_personality"] extern fn eh_personality() {} -#[cfg(target_os = "windows")] -#[lang = "eh_unwind_resume"] -extern fn eh_unwind_resume() {} - // take a reference to any built-in range fn take_range(_r: &impl RangeBounds) {} diff --git a/src/test/ui/range/issue-54505-no-std.stderr b/src/test/ui/range/issue-54505-no-std.stderr index aead80fa500a9..909340611328a 100644 --- a/src/test/ui/range/issue-54505-no-std.stderr +++ b/src/test/ui/range/issue-54505-no-std.stderr @@ -1,7 +1,7 @@ error: `#[panic_handler]` function required, but not found error[E0308]: mismatched types - --> $DIR/issue-54505-no-std.rs:28:16 + --> $DIR/issue-54505-no-std.rs:24:16 | LL | take_range(0..1); | ^^^^ @@ -13,7 +13,7 @@ LL | take_range(0..1); found struct `core::ops::Range<{integer}>` error[E0308]: mismatched types - --> $DIR/issue-54505-no-std.rs:33:16 + --> $DIR/issue-54505-no-std.rs:29:16 | LL | take_range(1..); | ^^^ @@ -25,7 +25,7 @@ LL | take_range(1..); found struct `core::ops::RangeFrom<{integer}>` error[E0308]: mismatched types - --> $DIR/issue-54505-no-std.rs:38:16 + --> $DIR/issue-54505-no-std.rs:34:16 | LL | take_range(..); | ^^ @@ -37,7 +37,7 @@ LL | take_range(..); found struct `core::ops::RangeFull` error[E0308]: mismatched types - --> $DIR/issue-54505-no-std.rs:43:16 + --> $DIR/issue-54505-no-std.rs:39:16 | LL | take_range(0..=1); | ^^^^^ @@ -49,7 +49,7 @@ LL | take_range(0..=1); found struct `core::ops::RangeInclusive<{integer}>` error[E0308]: mismatched types - --> $DIR/issue-54505-no-std.rs:48:16 + --> $DIR/issue-54505-no-std.rs:44:16 | LL | take_range(..5); | ^^^ @@ -61,7 +61,7 @@ LL | take_range(..5); found struct `core::ops::RangeTo<{integer}>` error[E0308]: mismatched types - --> $DIR/issue-54505-no-std.rs:53:16 + --> $DIR/issue-54505-no-std.rs:49:16 | LL | take_range(..=42); | ^^^^^