diff --git a/library/panic_abort/src/lib.rs b/library/panic_abort/src/lib.rs index eb2277d8baacd..0347df2d63717 100644 --- a/library/panic_abort/src/lib.rs +++ b/library/panic_abort/src/lib.rs @@ -116,6 +116,19 @@ pub mod personalities { )))] pub extern "C" fn rust_eh_personality() {} + // On *-pc-windows-msvc we need such a symbol to make linker happy. + #[allow(non_snake_case)] + #[no_mangle] + #[cfg(all(target_os = "windows", target_env = "msvc"))] + pub extern "C" fn __CxxFrameHandler3( + _record: usize, + _frame: usize, + _context: usize, + _dispatcher: usize, + ) -> u32 { + 1 + } + // On x86_64-pc-windows-gnu we use our own personality function that needs // to return `ExceptionContinueSearch` as we're passing on all our frames. #[rustc_std_internal_symbol] diff --git a/src/test/ui/panic-runtime/abort-link-to-unwind-msvc-no-std-link-to-libcmt.rs b/src/test/ui/panic-runtime/abort-link-to-unwind-msvc-no-std-link-to-libcmt.rs new file mode 100644 index 0000000000000..324bd7e296dab --- /dev/null +++ b/src/test/ui/panic-runtime/abort-link-to-unwind-msvc-no-std-link-to-libcmt.rs @@ -0,0 +1,25 @@ +// run-fail +// compile-flags: -C panic=abort -C target-feature=+crt-static +// aux-build:exit-success-if-unwind-msvc-no-std.rs +// only-msvc +// Test that `no_std` with `panic=abort` under MSVC toolchain +// doesn't cause error when linking to libcmt. +// We don't run this executable because it will hang in `rust_begin_unwind` + +#![no_std] +#![no_main] + +extern crate exit_success_if_unwind_msvc_no_std; + +#[link(name = "libcmt")] +extern "C" {} + +#[no_mangle] +pub extern "C" fn main() -> i32 { + exit_success_if_unwind_msvc_no_std::bar(do_panic); + 0 +} + +fn do_panic() { + panic!(); +} diff --git a/src/test/ui/panic-runtime/abort-link-to-unwind-msvc-no-std-link-to-msvcrt.rs b/src/test/ui/panic-runtime/abort-link-to-unwind-msvc-no-std-link-to-msvcrt.rs new file mode 100644 index 0000000000000..11c8b1d033d80 --- /dev/null +++ b/src/test/ui/panic-runtime/abort-link-to-unwind-msvc-no-std-link-to-msvcrt.rs @@ -0,0 +1,25 @@ +// run-fail +// compile-flags: -C panic=abort +// aux-build:exit-success-if-unwind-msvc-no-std.rs +// only-msvc +// Test that `no_std` with `panic=abort` under MSVC toolchain +// doesn't cause error when linking to msvcrt. +// We don't run this executable because it will hang in `rust_begin_unwind` + +#![no_std] +#![no_main] + +extern crate exit_success_if_unwind_msvc_no_std; + +#[link(name = "msvcrt")] +extern "C" {} + +#[no_mangle] +pub extern "C" fn main() -> i32 { + exit_success_if_unwind_msvc_no_std::bar(do_panic); + 0 +} + +fn do_panic() { + panic!(); +} diff --git a/src/test/ui/panic-runtime/abort-link-to-unwind-msvc-no-std.rs b/src/test/ui/panic-runtime/abort-link-to-unwind-msvc-no-std.rs new file mode 100644 index 0000000000000..a738a39d78001 --- /dev/null +++ b/src/test/ui/panic-runtime/abort-link-to-unwind-msvc-no-std.rs @@ -0,0 +1,52 @@ +// run-fail +// compile-flags:-C panic=abort +// aux-build:exit-success-if-unwind-msvc-no-std.rs +// no-prefer-dynamic +// only-msvc +// We don't run this executable because it will hang in `rust_begin_unwind` + +#![no_std] +#![no_main] +#![windows_subsystem = "console"] +#![feature(panic_abort)] + +extern crate exit_success_if_unwind_msvc_no_std; +extern crate panic_abort; + +#[no_mangle] +pub unsafe extern "C" fn memcpy(dest: *mut u8, _src: *const u8, _n: usize) -> *mut u8 { + dest +} + +#[no_mangle] +pub unsafe extern "C" fn memmove(dest: *mut u8, _src: *const u8, _n: usize) -> *mut u8 { + dest +} + +#[no_mangle] +pub unsafe extern "C" fn memset(mem: *mut u8, _val: i32, _n: usize) -> *mut u8 { + mem +} + +#[no_mangle] +pub unsafe extern "C" fn memcmp(_mem1: *const u8, _mem2: *const u8, _n: usize) -> i32 { + 0 +} + +// Used by compiler_builtins +#[no_mangle] +#[used] +static _fltused: i32 = 0; + +// MSVC always assumes that some functions are avaliable +#[link(name = "ntdll")] +extern "system" {} + +#[no_mangle] +pub extern "C" fn mainCRTStartup() { + exit_success_if_unwind_msvc_no_std::bar(main); +} + +fn main() { + panic!(); +} diff --git a/src/test/ui/panic-runtime/auxiliary/exit-success-if-unwind-msvc-no-std.rs b/src/test/ui/panic-runtime/auxiliary/exit-success-if-unwind-msvc-no-std.rs new file mode 100644 index 0000000000000..e2be90f5addb0 --- /dev/null +++ b/src/test/ui/panic-runtime/auxiliary/exit-success-if-unwind-msvc-no-std.rs @@ -0,0 +1,32 @@ +// compile-flags:-C panic=unwind +// no-prefer-dynamic + +#![no_std] +#![crate_type = "rlib"] +#![feature(core_intrinsics)] + +struct Bomb; + +impl Drop for Bomb { + fn drop(&mut self) { + #[link(name = "kernel32")] + extern "system" { + fn ExitProcess(code: u32) -> !; + } + unsafe { + ExitProcess(0); + } + } +} + +pub fn bar(f: fn()) { + let _bomb = Bomb; + f(); +} + +use core::panic::PanicInfo; + +#[panic_handler] +fn handle_panic(_: &PanicInfo) -> ! { + core::intrinsics::abort(); +} diff --git a/src/test/ui/panic-runtime/unwind-msvc-no-std-link-to-libcmt.rs b/src/test/ui/panic-runtime/unwind-msvc-no-std-link-to-libcmt.rs new file mode 100644 index 0000000000000..b27b95ee050f9 --- /dev/null +++ b/src/test/ui/panic-runtime/unwind-msvc-no-std-link-to-libcmt.rs @@ -0,0 +1,47 @@ +// build-pass +// compile-flags: -C panic=unwind -C target-feature=+crt-static +// only-msvc +// Test that `no_std` with `panic=unwind` under MSVC toolchain +// doesn't cause error when linking to libcmt. + +#![no_std] +#![no_main] +#![feature(alloc_error_handler)] +#![feature(panic_unwind)] + +use core::alloc::{GlobalAlloc, Layout}; + +struct DummyAllocator; + +unsafe impl GlobalAlloc for DummyAllocator { + unsafe fn alloc(&self, _layout: Layout) -> *mut u8 { + core::ptr::null_mut() + } + + unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {} +} + +#[global_allocator] +static ALLOC: DummyAllocator = DummyAllocator; + +#[alloc_error_handler] +fn rust_oom(_layout: Layout) -> ! { + panic!() +} + +extern crate panic_unwind; + +use core::panic::PanicInfo; + +#[panic_handler] +fn handle_panic(_: &PanicInfo) -> ! { + loop {} +} + +#[link(name = "libcmt")] +extern "C" {} + +#[no_mangle] +pub extern "C" fn main() -> i32 { + panic!(); +} diff --git a/src/test/ui/panic-runtime/unwind-msvc-no-std-link-to-msvcrt.rs b/src/test/ui/panic-runtime/unwind-msvc-no-std-link-to-msvcrt.rs new file mode 100644 index 0000000000000..95036e5774cee --- /dev/null +++ b/src/test/ui/panic-runtime/unwind-msvc-no-std-link-to-msvcrt.rs @@ -0,0 +1,47 @@ +// build-pass +// compile-flags: -C panic=unwind +// only-msvc +// Test that `no_std` with `panic=unwind` under MSVC toolchain +// doesn't cause error when linking to msvcrt. + +#![no_std] +#![no_main] +#![feature(alloc_error_handler)] +#![feature(panic_unwind)] + +use core::alloc::{GlobalAlloc, Layout}; + +struct DummyAllocator; + +unsafe impl GlobalAlloc for DummyAllocator { + unsafe fn alloc(&self, _layout: Layout) -> *mut u8 { + core::ptr::null_mut() + } + + unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {} +} + +#[global_allocator] +static ALLOC: DummyAllocator = DummyAllocator; + +#[alloc_error_handler] +fn rust_oom(_layout: Layout) -> ! { + panic!() +} + +extern crate panic_unwind; + +use core::panic::PanicInfo; + +#[panic_handler] +fn handle_panic(_: &PanicInfo) -> ! { + loop {} +} + +#[link(name = "msvcrt")] +extern "C" {} + +#[no_mangle] +pub extern "C" fn main() -> i32 { + panic!(); +}