Skip to content

Commit 3ef75d5

Browse files
committed
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.
1 parent e4e67bd commit 3ef75d5

File tree

9 files changed

+33
-0
lines changed

9 files changed

+33
-0
lines changed

src/libcore/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
#![feature(optin_builtin_traits)]
8080
#![feature(reflect)]
8181
#![feature(rustc_attrs)]
82+
#![feature(unwind_attributes)]
8283
#![cfg_attr(stage0, feature(simd))]
8384
#![cfg_attr(not(stage0), feature(repr_simd, platform_intrinsics))]
8485
#![feature(staged_api)]

src/libcore/panicking.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ pub fn panic_fmt(fmt: fmt::Arguments, file_line: &(&'static str, u32)) -> ! {
6262
#[allow(improper_ctypes)]
6363
extern {
6464
#[lang = "panic_fmt"]
65+
#[unwind]
6566
fn panic_impl(fmt: fmt::Arguments, file: &'static str, line: u32) -> !;
6667
}
6768
let (file, line) = *file_line;

src/librustc_trans/trans/foreign.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ pub fn register_foreign_item_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
211211
let llfn_ty = lltype_for_fn_from_foreign_types(ccx, &tys);
212212

213213
let llfn = get_extern_fn(ccx, &mut *ccx.externs().borrow_mut(), name, cc, llfn_ty, fty);
214+
attributes::unwind(llfn, false);
214215
add_argument_attributes(&tys, llfn);
215216
attributes::from_fn_attrs(ccx, attrs, llfn);
216217
llfn

src/libstd/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@
243243
#![feature(unique)]
244244
#![feature(unsafe_no_drop_flag, filling_drop)]
245245
#![feature(decode_utf16)]
246+
#![feature(unwind_attributes)]
246247
#![feature(vec_push_all)]
247248
#![feature(vec_resize)]
248249
#![feature(wrapping)]

src/libstd/sys/common/libunwind.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,10 +124,12 @@ extern "C" {
124124
// iOS on armv7 uses SjLj exceptions and requires to link
125125
// against corresponding routine (..._SjLj_...)
126126
#[cfg(not(all(target_os = "ios", target_arch = "arm")))]
127+
#[unwind]
127128
pub fn _Unwind_RaiseException(exception: *mut _Unwind_Exception)
128129
-> _Unwind_Reason_Code;
129130

130131
#[cfg(all(target_os = "ios", target_arch = "arm"))]
132+
#[unwind]
131133
fn _Unwind_SjLj_RaiseException(e: *mut _Unwind_Exception)
132134
-> _Unwind_Reason_Code;
133135

src/libstd/sys/common/unwind/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ fn rust_panic(cause: Box<Any + Send + 'static>) -> ! {
192192
#[cfg(not(test))]
193193
/// Entry point of panic from the libcore crate.
194194
#[lang = "panic_fmt"]
195+
#[unwind]
195196
pub extern fn rust_begin_unwind(msg: fmt::Arguments,
196197
file: &'static str, line: u32) -> ! {
197198
begin_unwind_fmt(msg, &(file, line))

src/libstd/sys/common/unwind/seh.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ static PANIC_DATA: StaticKey = StaticKey::new(None);
6262

6363
// This function is provided by kernel32.dll
6464
extern "system" {
65+
#[unwind]
6566
fn RaiseException(dwExceptionCode: DWORD,
6667
dwExceptionFlags: DWORD,
6768
nNumberOfArguments: DWORD,

src/libstd/sys/common/unwind/seh64_gnu.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ pub enum EXCEPTION_DISPOSITION {
9393

9494
// From kernel32.dll
9595
extern "system" {
96+
#[unwind]
9697
fn RaiseException(dwExceptionCode: DWORD,
9798
dwExceptionFlags: DWORD,
9899
nNumberOfArguments: DWORD,
@@ -198,6 +199,7 @@ unsafe extern fn rust_eh_personality(
198199

199200
#[lang = "eh_unwind_resume"]
200201
#[cfg(not(test))]
202+
#[unwind]
201203
unsafe extern fn rust_eh_unwind_resume(panic_ctx: LPVOID) {
202204
let params = [panic_ctx as ULONG_PTR];
203205
RaiseException(RUST_PANIC,

src/test/codegen/extern-functions.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// compile-flags: -C no-prepopulate-passes
12+
13+
#![feature(unwind_attributes)]
14+
15+
extern {
16+
// CHECK: Function Attrs: nounwind
17+
// CHECK-NEXT: declare void @extern_fn
18+
fn extern_fn();
19+
// CHECK-NOT: Function Attrs: nounwind
20+
// CHECK: declare void @unwinding_extern_fn
21+
#[unwind]
22+
fn unwinding_extern_fn();
23+
}

0 commit comments

Comments
 (0)