Skip to content

Commit 457ba44

Browse files
Switch eh_unwind_resume to be a static function ptr
This makes calls go directly to _Unwind_Resume. _Unwind_Resume expects that it is called directly (i.e., the caller needs to be the landing pad).
1 parent a2d6604 commit 457ba44

File tree

17 files changed

+145
-74
lines changed

17 files changed

+145
-74
lines changed

src/doc/unstable-book/src/language-features/lang-items.md

+10-4
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,11 @@ fn main(_argc: isize, _argv: *const *const u8) -> isize {
5252
5353
#[lang = "eh_personality"] extern fn rust_eh_personality() {}
5454
#[lang = "panic_impl"] extern fn rust_begin_panic(info: &PanicInfo) -> ! { unsafe { intrinsics::abort() } }
55-
#[lang = "eh_unwind_resume"] extern fn rust_eh_unwind_resume() {}
55+
extern "C" fn eh_unwind_resume(_: *mut u8) -> ! {
56+
loop {}
57+
}
58+
#[lang = "eh_unwind_resume"]
59+
static _RESUME: fn(*mut u8) -> ! = eh_unwind_resume;
5660
#[no_mangle] pub extern fn rust_eh_register_frames () {}
5761
#[no_mangle] pub extern fn rust_eh_unregister_frames () {}
5862
```
@@ -131,10 +135,12 @@ pub extern fn rust_eh_personality() {
131135
}
132136
133137
// This function may be needed based on the compilation target.
134-
#[lang = "eh_unwind_resume"]
135-
#[no_mangle]
136-
pub extern fn rust_eh_unwind_resume() {
138+
extern "C" fn eh_unwind_resume(_: *mut u8) -> ! {
139+
loop {}
137140
}
141+
#[lang = "eh_unwind_resume"]
142+
static _RESUME: fn(*mut u8) -> ! = eh_unwind_resume;
143+
138144
139145
#[lang = "panic_impl"]
140146
#[no_mangle]

src/libpanic_unwind/gcc.rs

+13-7
Original file line numberDiff line numberDiff line change
@@ -324,19 +324,25 @@ unsafe fn find_eh_action(
324324
eh::find_eh_action(lsda, &eh_context, foreign_exception)
325325
}
326326

327-
// See docs in the `unwind` module.
327+
#[cfg(all(
328+
target_os = "windows",
329+
any(target_arch = "x86", target_arch = "x86_64"),
330+
target_env = "gnu"
331+
))]
332+
#[cfg_attr(not(bootstrap), lang = "eh_unwind_resume")]
333+
#[used]
334+
pub static RESUME: unsafe extern "C" fn(*mut uw::_Unwind_Exception) -> ! =
335+
uw::_Unwind_Resume as unsafe extern "C" fn(_) -> !;
336+
328337
#[cfg(all(
329338
target_os = "windows",
330339
any(target_arch = "x86", target_arch = "x86_64"),
331340
target_env = "gnu"
332341
))]
333342
#[lang = "eh_unwind_resume"]
334-
#[unwind(allowed)]
335-
// This must always be inlined because _Unwind_Resume expects to be called
336-
// directly from the landing pad.
337-
#[cfg_attr(not(bootstrap), inline(always))]
338-
unsafe extern "C" fn rust_eh_unwind_resume(panic_ctx: *mut u8) -> ! {
339-
uw::_Unwind_Resume(panic_ctx as *mut uw::_Unwind_Exception);
343+
#[cfg(bootstrap)]
344+
pub unsafe extern "C" fn rust_eh_unwind_resume(p: *mut u8) -> ! {
345+
uw::_Unwind_Resume(p as *mut uw::_Unwind_Exception)
340346
}
341347

342348
// Frame unwind info registration

src/libpanic_unwind/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#![feature(raw)]
3131
#![panic_runtime]
3232
#![feature(panic_runtime)]
33+
#![allow(dead_code)]
3334

3435
use alloc::boxed::Box;
3536
use core::any::Any;

src/librustc/middle/lang_items.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ language_item_table! {
385385
StartFnLangItem, "start", start_fn, Target::Fn;
386386

387387
EhPersonalityLangItem, "eh_personality", eh_personality, Target::Fn;
388-
EhUnwindResumeLangItem, "eh_unwind_resume", eh_unwind_resume, Target::Fn;
388+
EhUnwindResumeLangItem, "eh_unwind_resume", eh_unwind_resume, Target::Static;
389389
EhCatchTypeinfoLangItem, "eh_catch_typeinfo", eh_catch_typeinfo, Target::Static;
390390

391391
OwnedBoxLangItem, "owned_box", owned_box, Target::Struct;

src/librustc_codegen_llvm/context.rs

+6-13
Original file line numberDiff line numberDiff line change
@@ -407,17 +407,9 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
407407
let tcx = self.tcx;
408408
assert!(self.sess().target.target.options.custom_unwind_resume);
409409
if let Some(def_id) = tcx.lang_items().eh_unwind_resume() {
410-
let llfn = self.get_fn_addr(
411-
ty::Instance::resolve(
412-
tcx,
413-
ty::ParamEnv::reveal_all(),
414-
def_id,
415-
tcx.intern_substs(&[]),
416-
)
417-
.unwrap(),
418-
);
419-
unwresume.set(Some(llfn));
420-
return llfn;
410+
let static_ptr = self.get_static(def_id);
411+
unwresume.set(Some(static_ptr));
412+
return static_ptr;
421413
}
422414

423415
let sig = ty::Binder::bind(tcx.mk_fn_sig(
@@ -431,8 +423,9 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
431423
let fn_abi = FnAbi::of_fn_ptr(self, sig, &[]);
432424
let llfn = self.declare_fn("rust_eh_unwind_resume", &fn_abi);
433425
attributes::apply_target_cpu_attr(self, llfn);
434-
unwresume.set(Some(llfn));
435-
llfn
426+
let static_ptr = self.static_addr_of(llfn, tcx.data_layout.pointer_align.abi, None);
427+
unwresume.set(Some(static_ptr));
428+
static_ptr
436429
}
437430

438431
fn sess(&self) -> &Session {

src/librustc_codegen_ssa/mir/block.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
184184
lp = bx.insert_value(lp, lp1, 1);
185185
bx.resume(lp);
186186
} else {
187-
bx.call(bx.eh_unwind_resume(), &[lp0], helper.funclet(self));
187+
bx.call(
188+
bx.load(bx.eh_unwind_resume(), bx.tcx().data_layout.pointer_align.abi),
189+
&[lp0],
190+
helper.funclet(self),
191+
);
188192
bx.unreachable();
189193
}
190194
}

src/libunwind/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#![feature(nll)]
55
#![feature(staged_api)]
66
#![feature(unwind_attributes)]
7+
#![feature(lang_items)]
78
#![feature(static_nobundle)]
89
#![cfg_attr(not(target_env = "msvc"), feature(libc))]
910

Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
11
// no-prefer-dynamic
22

33
#![crate_type = "rlib"]
4-
54
#![no_std]
65
#![feature(lang_items)]
76

87
use core::panic::PanicInfo;
98

109
#[lang = "panic_impl"]
11-
fn panic_impl(info: &PanicInfo) -> ! { loop {} }
10+
fn panic_impl(info: &PanicInfo) -> ! {
11+
loop {}
12+
}
1213
#[lang = "eh_personality"]
1314
fn eh_personality() {}
15+
16+
unsafe extern "C" fn eh_unwind_resume(_: *mut u8) -> ! {
17+
loop {}
18+
}
1419
#[lang = "eh_unwind_resume"]
15-
fn eh_unwind_resume() {}
20+
static _RESUME: unsafe extern "C" fn(*mut u8) -> ! = eh_unwind_resume;

src/test/ui/consts/const-eval/const_panic_libcore_main.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,12 @@ const X: () = unimplemented!();
1717

1818
#[lang = "eh_personality"]
1919
fn eh() {}
20+
21+
unsafe extern "C" fn eh_unwind_resume(_: *mut u8) -> ! {
22+
loop {}
23+
}
2024
#[lang = "eh_unwind_resume"]
21-
fn eh_unwind_resume() {}
25+
static _RESUME: unsafe extern "C" fn(*mut u8) -> ! = eh_unwind_resume;
2226

2327
#[panic_handler]
2428
fn panic(_info: &PanicInfo) -> ! {

src/test/ui/macros/macro-comma-behavior.core.stderr

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,41 @@
11
error: 1 positional argument in format string, but no arguments were given
2-
--> $DIR/macro-comma-behavior.rs:21:23
2+
--> $DIR/macro-comma-behavior.rs:36:23
33
|
44
LL | assert_eq!(1, 1, "{}",);
55
| ^^
66

77
error: 1 positional argument in format string, but no arguments were given
8-
--> $DIR/macro-comma-behavior.rs:24:23
8+
--> $DIR/macro-comma-behavior.rs:39:23
99
|
1010
LL | assert_ne!(1, 2, "{}",);
1111
| ^^
1212

1313
error: 1 positional argument in format string, but no arguments were given
14-
--> $DIR/macro-comma-behavior.rs:30:29
14+
--> $DIR/macro-comma-behavior.rs:45:29
1515
|
1616
LL | debug_assert_eq!(1, 1, "{}",);
1717
| ^^
1818

1919
error: 1 positional argument in format string, but no arguments were given
20-
--> $DIR/macro-comma-behavior.rs:33:29
20+
--> $DIR/macro-comma-behavior.rs:48:29
2121
|
2222
LL | debug_assert_ne!(1, 2, "{}",);
2323
| ^^
2424

2525
error: 1 positional argument in format string, but no arguments were given
26-
--> $DIR/macro-comma-behavior.rs:54:19
26+
--> $DIR/macro-comma-behavior.rs:72:19
2727
|
2828
LL | format_args!("{}",);
2929
| ^^
3030

3131
error: 1 positional argument in format string, but no arguments were given
32-
--> $DIR/macro-comma-behavior.rs:72:21
32+
--> $DIR/macro-comma-behavior.rs:92:21
3333
|
3434
LL | unimplemented!("{}",);
3535
| ^^
3636

3737
error: 1 positional argument in format string, but no arguments were given
38-
--> $DIR/macro-comma-behavior.rs:81:24
38+
--> $DIR/macro-comma-behavior.rs:101:24
3939
|
4040
LL | write!(f, "{}",)?;
4141
| ^^

src/test/ui/macros/macro-comma-behavior.rs

+30-10
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,26 @@
66
#![feature(lang_items)]
77
#![cfg_attr(core, no_std)]
88

9-
#[cfg(std)] use std::fmt;
10-
#[cfg(core)] use core::fmt;
11-
#[cfg(core)] #[lang = "eh_personality"] fn eh_personality() {}
12-
#[cfg(core)] #[lang = "eh_unwind_resume"] fn eh_unwind_resume() {}
13-
#[cfg(core)] #[lang = "panic_impl"] fn panic_impl(panic: &core::panic::PanicInfo) -> ! { loop {} }
9+
#[cfg(core)]
10+
use core::fmt;
11+
#[cfg(std)]
12+
use std::fmt;
13+
#[cfg(core)]
14+
#[lang = "eh_personality"]
15+
fn eh_personality() {}
16+
#[cfg(core)]
17+
#[lang = "panic_impl"]
18+
fn panic_impl(panic: &core::panic::PanicInfo) -> ! {
19+
loop {}
20+
}
21+
22+
#[cfg(core)]
23+
unsafe extern "C" fn eh_unwind_resume(_: *mut u8) -> ! {
24+
loop {}
25+
}
26+
#[cfg(core)]
27+
#[lang = "eh_unwind_resume"]
28+
static _RESUME: unsafe extern "C" fn(*mut u8) -> ! = eh_unwind_resume;
1429

1530
// (see documentation of the similarly-named test in run-pass)
1631
fn to_format_or_not_to_format() {
@@ -34,19 +49,22 @@ fn to_format_or_not_to_format() {
3449
//[core]~^ ERROR no arguments
3550
//[std]~^^ ERROR no arguments
3651

37-
#[cfg(std)] {
52+
#[cfg(std)]
53+
{
3854
eprint!("{}",);
3955
//[std]~^ ERROR no arguments
4056
}
4157

42-
#[cfg(std)] {
58+
#[cfg(std)]
59+
{
4360
// FIXME: compile-fail says "expected error not found" even though
4461
// rustc does emit an error
4562
// eprintln!("{}",);
4663
// <DISABLED> [std]~^ ERROR no arguments
4764
}
4865

49-
#[cfg(std)] {
66+
#[cfg(std)]
67+
{
5068
format!("{}",);
5169
//[std]~^ ERROR no arguments
5270
}
@@ -57,12 +75,14 @@ fn to_format_or_not_to_format() {
5775

5876
// if falsum() { panic!("{}",); } // see run-pass
5977

60-
#[cfg(std)] {
78+
#[cfg(std)]
79+
{
6180
print!("{}",);
6281
//[std]~^ ERROR no arguments
6382
}
6483

65-
#[cfg(std)] {
84+
#[cfg(std)]
85+
{
6686
// FIXME: compile-fail says "expected error not found" even though
6787
// rustc does emit an error
6888
// println!("{}",);

src/test/ui/macros/macro-comma-behavior.std.stderr

+10-10
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,59 @@
11
error: 1 positional argument in format string, but no arguments were given
2-
--> $DIR/macro-comma-behavior.rs:21:23
2+
--> $DIR/macro-comma-behavior.rs:36:23
33
|
44
LL | assert_eq!(1, 1, "{}",);
55
| ^^
66

77
error: 1 positional argument in format string, but no arguments were given
8-
--> $DIR/macro-comma-behavior.rs:24:23
8+
--> $DIR/macro-comma-behavior.rs:39:23
99
|
1010
LL | assert_ne!(1, 2, "{}",);
1111
| ^^
1212

1313
error: 1 positional argument in format string, but no arguments were given
14-
--> $DIR/macro-comma-behavior.rs:30:29
14+
--> $DIR/macro-comma-behavior.rs:45:29
1515
|
1616
LL | debug_assert_eq!(1, 1, "{}",);
1717
| ^^
1818

1919
error: 1 positional argument in format string, but no arguments were given
20-
--> $DIR/macro-comma-behavior.rs:33:29
20+
--> $DIR/macro-comma-behavior.rs:48:29
2121
|
2222
LL | debug_assert_ne!(1, 2, "{}",);
2323
| ^^
2424

2525
error: 1 positional argument in format string, but no arguments were given
26-
--> $DIR/macro-comma-behavior.rs:38:18
26+
--> $DIR/macro-comma-behavior.rs:54:18
2727
|
2828
LL | eprint!("{}",);
2929
| ^^
3030

3131
error: 1 positional argument in format string, but no arguments were given
32-
--> $DIR/macro-comma-behavior.rs:50:18
32+
--> $DIR/macro-comma-behavior.rs:68:18
3333
|
3434
LL | format!("{}",);
3535
| ^^
3636

3737
error: 1 positional argument in format string, but no arguments were given
38-
--> $DIR/macro-comma-behavior.rs:54:19
38+
--> $DIR/macro-comma-behavior.rs:72:19
3939
|
4040
LL | format_args!("{}",);
4141
| ^^
4242

4343
error: 1 positional argument in format string, but no arguments were given
44-
--> $DIR/macro-comma-behavior.rs:61:17
44+
--> $DIR/macro-comma-behavior.rs:80:17
4545
|
4646
LL | print!("{}",);
4747
| ^^
4848

4949
error: 1 positional argument in format string, but no arguments were given
50-
--> $DIR/macro-comma-behavior.rs:72:21
50+
--> $DIR/macro-comma-behavior.rs:92:21
5151
|
5252
LL | unimplemented!("{}",);
5353
| ^^
5454

5555
error: 1 positional argument in format string, but no arguments were given
56-
--> $DIR/macro-comma-behavior.rs:81:24
56+
--> $DIR/macro-comma-behavior.rs:101:24
5757
|
5858
LL | write!(f, "{}",)?;
5959
| ^^

src/test/ui/no_owned_box_lang_item.rs

+11-3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,14 @@ fn main() {
1111
let x = box 1i32;
1212
}
1313

14-
#[lang = "eh_personality"] extern fn eh_personality() {}
15-
#[lang = "eh_unwind_resume"] extern fn eh_unwind_resume() {}
16-
#[lang = "panic_impl"] fn panic_impl(panic: &PanicInfo) -> ! { loop {} }
14+
#[lang = "eh_personality"]
15+
extern "C" fn eh_personality() {}
16+
extern "C" fn eh_unwind_resume(_: *mut u8) -> ! {
17+
loop {}
18+
}
19+
#[lang = "eh_unwind_resume"]
20+
static _RESUME: fn(*mut u8) -> ! = eh_unwind_resume;
21+
#[lang = "panic_impl"]
22+
fn panic_impl(panic: &PanicInfo) -> ! {
23+
loop {}
24+
}

0 commit comments

Comments
 (0)