Skip to content

Commit a866124

Browse files
committed
Auto merge of #83482 - hyd-dev:uwtable, r=nagisa
Allow using `-C force-unwind-tables=no` when `panic=unwind` It seems LLVM still generates proper unwind tables even there is no `uwtable` attribute, unless I looked at the wrong place 🤔: https://github.com/llvm/llvm-project/blob/c21016715f0ee4a36affdf7150ac135ca98b0eae/llvm/include/llvm/IR/Function.h#L666 Therefore, I *assume* it's safe to omit `uwtable` even when `panic=unwind`, and this PR removes the restriction that disallows using `-C force-unwind-tables=no` when `panic=unwind`.
2 parents 7953910 + 2fd4dd2 commit a866124

7 files changed

+74
-27
lines changed

compiler/rustc_session/src/session.rs

+9-16
Original file line numberDiff line numberDiff line change
@@ -807,8 +807,11 @@ impl Session {
807807
// This is used to control the emission of the `uwtable` attribute on
808808
// LLVM functions.
809809
//
810-
// At the very least, unwind tables are needed when compiling with
811-
// `-C panic=unwind`.
810+
// Unwind tables are needed when compiling with `-C panic=unwind`, but
811+
// LLVM won't omit unwind tables unless the function is also marked as
812+
// `nounwind`, so users are allowed to disable `uwtable` emission.
813+
// Historically rustc always emits `uwtable` attributes by default, so
814+
// even they can be disabled, they're still emitted by default.
812815
//
813816
// On some targets (including windows), however, exceptions include
814817
// other events such as illegal instructions, segfaults, etc. This means
@@ -821,13 +824,10 @@ impl Session {
821824
// If a target requires unwind tables, then they must be emitted.
822825
// Otherwise, we can defer to the `-C force-unwind-tables=<yes/no>`
823826
// value, if it is provided, or disable them, if not.
824-
if self.panic_strategy() == PanicStrategy::Unwind {
825-
true
826-
} else if self.target.requires_uwtable {
827-
true
828-
} else {
829-
self.opts.cg.force_unwind_tables.unwrap_or(self.target.default_uwtable)
830-
}
827+
self.target.requires_uwtable
828+
|| self.opts.cg.force_unwind_tables.unwrap_or(
829+
self.panic_strategy() == PanicStrategy::Unwind || self.target.default_uwtable,
830+
)
831831
}
832832

833833
/// Returns the symbol name for the registrar function,
@@ -1483,13 +1483,6 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
14831483

14841484
// Unwind tables cannot be disabled if the target requires them.
14851485
if let Some(include_uwtables) = sess.opts.cg.force_unwind_tables {
1486-
if sess.panic_strategy() == PanicStrategy::Unwind && !include_uwtables {
1487-
sess.err(
1488-
"panic=unwind requires unwind tables, they cannot be disabled \
1489-
with `-C force-unwind-tables=no`.",
1490-
);
1491-
}
1492-
14931486
if sess.target.requires_uwtable && !include_uwtables {
14941487
sess.err(
14951488
"target requires unwind tables, they cannot be disabled with \
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// assembly-output: emit-asm
2+
// only-x86_64-unknown-linux-gnu
3+
// compile-flags: -C panic=unwind -C force-unwind-tables=n -O
4+
5+
#![crate_type = "lib"]
6+
7+
// CHECK-NOT: .cfi_startproc
8+
pub fn foo() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// assembly-output: emit-asm
2+
// only-x86_64-unknown-linux-gnu
3+
// compile-flags: -C panic=unwind -C force-unwind-tables=n
4+
5+
#![crate_type = "lib"]
6+
7+
// CHECK-LABEL: foo:
8+
// CHECK: .cfi_startproc
9+
#[no_mangle]
10+
fn foo() {
11+
panic!();
12+
}

src/test/codegen/force-no-unwind-tables.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,9 @@
33

44
#![crate_type="lib"]
55

6+
// CHECK-LABEL: define{{.*}}void @foo
67
// CHECK-NOT: attributes #{{.*}} uwtable
7-
pub fn foo() {}
8+
#[no_mangle]
9+
fn foo() {
10+
panic!();
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// compile-flags: -C panic=unwind -C no-prepopulate-passes
2+
3+
#![crate_type = "lib"]
4+
5+
// CHECK: attributes #{{.*}} uwtable
6+
pub fn foo() {}

src/test/ui/panic-runtime/unwind-tables-panic-required.rs

-10
This file was deleted.

src/test/ui/unwind-no-uwtable.rs

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// run-pass
2+
// ignore-windows target requires uwtable
3+
// ignore-wasm32-bare no proper panic=unwind support
4+
// compile-flags: -C panic=unwind -C force-unwind-tables=n
5+
6+
use std::panic::{self, AssertUnwindSafe};
7+
8+
struct Increase<'a>(&'a mut u8);
9+
10+
impl Drop for Increase<'_> {
11+
fn drop(&mut self) {
12+
*self.0 += 1;
13+
}
14+
}
15+
16+
#[inline(never)]
17+
fn unwind() {
18+
panic!();
19+
}
20+
21+
#[inline(never)]
22+
fn increase(count: &mut u8) {
23+
let _increase = Increase(count);
24+
unwind();
25+
}
26+
27+
fn main() {
28+
let mut count = 0;
29+
assert!(panic::catch_unwind(AssertUnwindSafe(
30+
#[inline(never)]
31+
|| increase(&mut count)
32+
)).is_err());
33+
assert_eq!(count, 1);
34+
}

0 commit comments

Comments
 (0)