]> git.proxmox.com Git - rustc.git/blame - src/test/ui/extern/issue-64655-extern-rust-must-allow-unwind.rs
New upstream version 1.53.0+dfsg1
[rustc.git] / src / test / ui / extern / issue-64655-extern-rust-must-allow-unwind.rs
CommitLineData
e1599b0c
XL
1// run-pass
2// ignore-wasm32-bare compiled with panic=abort by default
3// ignore-emscripten no threads support
4
5// rust-lang/rust#64655: with panic=unwind, a panic from a subroutine
6// should still run destructors as it unwinds the stack. However,
7// bugs with how the nounwind LLVM attribute was applied led to this
8// simple case being mishandled *if* you had optimization *and* fat
9// LTO turned on.
10
11// This test is the closest thing to a "regression test" we can do
12// without actually spawning subprocesses and comparing stderr
13// results.
14//
15// This test takes the code from the above issue and adapts it to
16// better fit our test infrastructure:
17//
18// * Instead of relying on `println!` to observe whether the destructor
19// is run, we instead run the code in a spawned thread and
20// communicate the destructor's operation via a synchronous atomic
21// in static memory.
22//
23// * To keep the output from confusing a casual user, we override the
24// panic hook to be a no-op (rather than printing a message to
25// stderr).
26//
27// (pnkfelix has confirmed by hand that these additions do not mask
28// the underlying bug.)
29
30// LTO settings cannot be combined with -C prefer-dynamic
31// no-prefer-dynamic
32
33// The revisions combine each lto setting with each optimization
34// setting; pnkfelix observed three differing behaviors at opt-levels
35// 0/1/2+3 for this test, so it seems prudent to be thorough.
36
37// revisions: no0 no1 no2 no3 thin0 thin1 thin2 thin3 fat0 fat1 fat2 fat3
38
39//[no0]compile-flags: -C opt-level=0 -C lto=no
40//[no1]compile-flags: -C opt-level=1 -C lto=no
41//[no2]compile-flags: -C opt-level=2 -C lto=no
42//[no3]compile-flags: -C opt-level=3 -C lto=no
cdc7bbd5
XL
43// FIXME(#83854) running this revision with 1 CGU triggers llvm assert in register allocator
44// when executed in dist-i586-gnu-i586-i686-musl runner.
45//[thin0]compile-flags: -C opt-level=0 -C lto=thin -Ccodegen-units=2
e1599b0c
XL
46//[thin1]compile-flags: -C opt-level=1 -C lto=thin
47//[thin2]compile-flags: -C opt-level=2 -C lto=thin
48//[thin3]compile-flags: -C opt-level=3 -C lto=thin
49//[fat0]compile-flags: -C opt-level=0 -C lto=fat
50//[fat1]compile-flags: -C opt-level=1 -C lto=fat
51//[fat2]compile-flags: -C opt-level=2 -C lto=fat
52//[fat3]compile-flags: -C opt-level=3 -C lto=fat
53
54fn main() {
55 use std::sync::atomic::{AtomicUsize, Ordering};
56
57 static SHARED: AtomicUsize = AtomicUsize::new(0);
58
59 assert_eq!(SHARED.fetch_add(0, Ordering::SeqCst), 0);
60
61 let old_hook = std::panic::take_hook();
62
63 std::panic::set_hook(Box::new(|_| { } )); // no-op on panic.
64
65 let handle = std::thread::spawn(|| {
66 struct Droppable;
67 impl Drop for Droppable {
68 fn drop(&mut self) {
69 SHARED.fetch_add(1, Ordering::SeqCst);
70 }
71 }
72
73 let _guard = Droppable;
74 None::<()>.expect("???");
75 });
76
77 let wait = handle.join();
78
79 // reinstate handler to ease observation of assertion failures.
80 std::panic::set_hook(old_hook);
81
82 assert!(wait.is_err());
83
84 assert_eq!(SHARED.fetch_add(0, Ordering::SeqCst), 1);
85}