From 3ef75d5774cb9a7cf839a69341c620b98fa9c7df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Fri, 11 Sep 2015 20:10:43 +0200 Subject: [PATCH] Mark all extern functions as nounwind Unwinding across an FFI boundary is undefined behaviour, so we can mark all external function as nounwind. The obvious exception are those functions that actually perform the unwinding. --- src/libcore/lib.rs | 1 + src/libcore/panicking.rs | 1 + src/librustc_trans/trans/foreign.rs | 1 + src/libstd/lib.rs | 1 + src/libstd/sys/common/libunwind.rs | 2 ++ src/libstd/sys/common/unwind/mod.rs | 1 + src/libstd/sys/common/unwind/seh.rs | 1 + src/libstd/sys/common/unwind/seh64_gnu.rs | 2 ++ src/test/codegen/extern-functions.rs | 23 +++++++++++++++++++++++ 9 files changed, 33 insertions(+) create mode 100644 src/test/codegen/extern-functions.rs diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 78a467e36579..94408072932e 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -79,6 +79,7 @@ #![feature(optin_builtin_traits)] #![feature(reflect)] #![feature(rustc_attrs)] +#![feature(unwind_attributes)] #![cfg_attr(stage0, feature(simd))] #![cfg_attr(not(stage0), feature(repr_simd, platform_intrinsics))] #![feature(staged_api)] diff --git a/src/libcore/panicking.rs b/src/libcore/panicking.rs index b443ae0636fa..93ddfa72f63c 100644 --- a/src/libcore/panicking.rs +++ b/src/libcore/panicking.rs @@ -62,6 +62,7 @@ pub fn panic_fmt(fmt: fmt::Arguments, file_line: &(&'static str, u32)) -> ! { #[allow(improper_ctypes)] extern { #[lang = "panic_fmt"] + #[unwind] fn panic_impl(fmt: fmt::Arguments, file: &'static str, line: u32) -> !; } let (file, line) = *file_line; diff --git a/src/librustc_trans/trans/foreign.rs b/src/librustc_trans/trans/foreign.rs index 9a5612495949..cbb092aa4eb3 100644 --- a/src/librustc_trans/trans/foreign.rs +++ b/src/librustc_trans/trans/foreign.rs @@ -211,6 +211,7 @@ pub fn register_foreign_item_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, let llfn_ty = lltype_for_fn_from_foreign_types(ccx, &tys); let llfn = get_extern_fn(ccx, &mut *ccx.externs().borrow_mut(), name, cc, llfn_ty, fty); + attributes::unwind(llfn, false); add_argument_attributes(&tys, llfn); attributes::from_fn_attrs(ccx, attrs, llfn); llfn diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index fca4c66112eb..dc370d8382a4 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -243,6 +243,7 @@ #![feature(unique)] #![feature(unsafe_no_drop_flag, filling_drop)] #![feature(decode_utf16)] +#![feature(unwind_attributes)] #![feature(vec_push_all)] #![feature(vec_resize)] #![feature(wrapping)] diff --git a/src/libstd/sys/common/libunwind.rs b/src/libstd/sys/common/libunwind.rs index fde612014e99..c6bffb0f733e 100644 --- a/src/libstd/sys/common/libunwind.rs +++ b/src/libstd/sys/common/libunwind.rs @@ -124,10 +124,12 @@ extern "C" { // iOS on armv7 uses SjLj exceptions and requires to link // against corresponding routine (..._SjLj_...) #[cfg(not(all(target_os = "ios", target_arch = "arm")))] + #[unwind] pub fn _Unwind_RaiseException(exception: *mut _Unwind_Exception) -> _Unwind_Reason_Code; #[cfg(all(target_os = "ios", target_arch = "arm"))] + #[unwind] fn _Unwind_SjLj_RaiseException(e: *mut _Unwind_Exception) -> _Unwind_Reason_Code; diff --git a/src/libstd/sys/common/unwind/mod.rs b/src/libstd/sys/common/unwind/mod.rs index ff93d0526b7e..738681c3cfed 100644 --- a/src/libstd/sys/common/unwind/mod.rs +++ b/src/libstd/sys/common/unwind/mod.rs @@ -192,6 +192,7 @@ fn rust_panic(cause: Box) -> ! { #[cfg(not(test))] /// Entry point of panic from the libcore crate. #[lang = "panic_fmt"] +#[unwind] pub extern fn rust_begin_unwind(msg: fmt::Arguments, file: &'static str, line: u32) -> ! { begin_unwind_fmt(msg, &(file, line)) diff --git a/src/libstd/sys/common/unwind/seh.rs b/src/libstd/sys/common/unwind/seh.rs index a201e406a23e..a89e8b499acc 100644 --- a/src/libstd/sys/common/unwind/seh.rs +++ b/src/libstd/sys/common/unwind/seh.rs @@ -62,6 +62,7 @@ static PANIC_DATA: StaticKey = StaticKey::new(None); // This function is provided by kernel32.dll extern "system" { + #[unwind] fn RaiseException(dwExceptionCode: DWORD, dwExceptionFlags: DWORD, nNumberOfArguments: DWORD, diff --git a/src/libstd/sys/common/unwind/seh64_gnu.rs b/src/libstd/sys/common/unwind/seh64_gnu.rs index 4d23794de244..9478678fda99 100644 --- a/src/libstd/sys/common/unwind/seh64_gnu.rs +++ b/src/libstd/sys/common/unwind/seh64_gnu.rs @@ -93,6 +93,7 @@ pub enum EXCEPTION_DISPOSITION { // From kernel32.dll extern "system" { + #[unwind] fn RaiseException(dwExceptionCode: DWORD, dwExceptionFlags: DWORD, nNumberOfArguments: DWORD, @@ -198,6 +199,7 @@ unsafe extern fn rust_eh_personality( #[lang = "eh_unwind_resume"] #[cfg(not(test))] +#[unwind] unsafe extern fn rust_eh_unwind_resume(panic_ctx: LPVOID) { let params = [panic_ctx as ULONG_PTR]; RaiseException(RUST_PANIC, diff --git a/src/test/codegen/extern-functions.rs b/src/test/codegen/extern-functions.rs new file mode 100644 index 000000000000..4c30b5ce02f4 --- /dev/null +++ b/src/test/codegen/extern-functions.rs @@ -0,0 +1,23 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -C no-prepopulate-passes + +#![feature(unwind_attributes)] + +extern { +// CHECK: Function Attrs: nounwind +// CHECK-NEXT: declare void @extern_fn + fn extern_fn(); +// CHECK-NOT: Function Attrs: nounwind +// CHECK: declare void @unwinding_extern_fn + #[unwind] + fn unwinding_extern_fn(); +}