mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-19 02:13:57 +00:00
Regression tests for issue 64655.
This commit is contained in:
parent
9fbb2a9b34
commit
a371972832
63
src/test/ui/extern/issue-64655-allow-unwind-when-calling-panic-directly.rs
vendored
Normal file
63
src/test/ui/extern/issue-64655-allow-unwind-when-calling-panic-directly.rs
vendored
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
// run-pass
|
||||||
|
|
||||||
|
// rust-lang/rust#64655: with panic=unwind, a panic from a subroutine
|
||||||
|
// should still run desstructors as it unwindws the stack. However,
|
||||||
|
// bugs with how the nounwind LLVM attribute was applied led to this
|
||||||
|
// simple case being mishandled *if* you had fat LTO turned on.
|
||||||
|
|
||||||
|
// Unlike issue-64655-extern-rust-must-allow-unwind.rs, the issue
|
||||||
|
// embodied in this test cropped up regardless of optimization level.
|
||||||
|
// Therefore it seemed worthy of being enshrined as a dedicated unit
|
||||||
|
// test.
|
||||||
|
|
||||||
|
// LTO settings cannot be combined with -C prefer-dynamic
|
||||||
|
// no-prefer-dynamic
|
||||||
|
|
||||||
|
// The revisions just enumerate lto settings (the opt-level appeared irrelevant in practice)
|
||||||
|
|
||||||
|
// revisions: no thin fat
|
||||||
|
//[no]compile-flags: -C lto=no
|
||||||
|
//[thin]compile-flags: -C lto=thin
|
||||||
|
//[fat]compile-flags: -C lto=fat
|
||||||
|
|
||||||
|
#![feature(core_panic)]
|
||||||
|
|
||||||
|
// (For some reason, reproducing the LTO issue requires pulling in std
|
||||||
|
// explicitly this way.)
|
||||||
|
#![no_std]
|
||||||
|
extern crate std;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
|
use std::boxed::Box;
|
||||||
|
|
||||||
|
static SHARED: AtomicUsize = AtomicUsize::new(0);
|
||||||
|
|
||||||
|
assert_eq!(SHARED.fetch_add(0, Ordering::SeqCst), 0);
|
||||||
|
|
||||||
|
let old_hook = std::panic::take_hook();
|
||||||
|
|
||||||
|
std::panic::set_hook(Box::new(|_| { } )); // no-op on panic.
|
||||||
|
|
||||||
|
let handle = std::thread::spawn(|| {
|
||||||
|
struct Droppable;
|
||||||
|
impl Drop for Droppable {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
SHARED.fetch_add(1, Ordering::SeqCst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let _guard = Droppable;
|
||||||
|
let s = "issue-64655-allow-unwind-when-calling-panic-directly.rs";
|
||||||
|
core::panicking::panic(&("???", s, 17, 4));
|
||||||
|
});
|
||||||
|
|
||||||
|
let wait = handle.join();
|
||||||
|
|
||||||
|
// reinstate handler to ease observation of assertion failures.
|
||||||
|
std::panic::set_hook(old_hook);
|
||||||
|
|
||||||
|
assert!(wait.is_err());
|
||||||
|
|
||||||
|
assert_eq!(SHARED.fetch_add(0, Ordering::SeqCst), 1);
|
||||||
|
}
|
82
src/test/ui/extern/issue-64655-extern-rust-must-allow-unwind.rs
vendored
Normal file
82
src/test/ui/extern/issue-64655-extern-rust-must-allow-unwind.rs
vendored
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
// run-pass
|
||||||
|
|
||||||
|
// rust-lang/rust#64655: with panic=unwind, a panic from a subroutine
|
||||||
|
// should still run desstructors as it unwindws the stack. However,
|
||||||
|
// bugs with how the nounwind LLVM attribute was applied led to this
|
||||||
|
// simple case being mishandled *if* you had optimization *and* fat
|
||||||
|
// LTO turned on.
|
||||||
|
|
||||||
|
// This test is the closest thing to a "regression test" we can do
|
||||||
|
// without actually spawning subprocesses and comparing stderr
|
||||||
|
// results.
|
||||||
|
//
|
||||||
|
// This test takes the code from the above issue and adapts it to
|
||||||
|
// better fit our test infrastructure:
|
||||||
|
//
|
||||||
|
// * Instead of relying on println! to observe whether the destructor
|
||||||
|
// is run, we instead run the code in a spawned thread and
|
||||||
|
// communicate the destructor's operation via a synchronous atomic
|
||||||
|
// in static memory.
|
||||||
|
//
|
||||||
|
// * To keep the output from confusing a casual user, we override the
|
||||||
|
// panic hook to be a no-op (rather than printing a message to
|
||||||
|
// stderr).
|
||||||
|
//
|
||||||
|
// (pnkfelix has confirmed by hand that these additions do not mask
|
||||||
|
// the underlying bug.)
|
||||||
|
|
||||||
|
// LTO settings cannot be combined with -C prefer-dynamic
|
||||||
|
// no-prefer-dynamic
|
||||||
|
|
||||||
|
// The revisions combine each lto setting with each optimization
|
||||||
|
// setting; pnkfelix observed three differing behaviors at opt-levels
|
||||||
|
// 0/1/2+3 for this test, so it seems prudent to be thorough.
|
||||||
|
|
||||||
|
// revisions: no0 no1 no2 no3 thin0 thin1 thin2 thin3 fat0 fat1 fat2 fat3
|
||||||
|
|
||||||
|
//[no0]compile-flags: -C opt-level=0 -C lto=no
|
||||||
|
//[no1]compile-flags: -C opt-level=1 -C lto=no
|
||||||
|
//[no2]compile-flags: -C opt-level=2 -C lto=no
|
||||||
|
//[no3]compile-flags: -C opt-level=3 -C lto=no
|
||||||
|
//[thin0]compile-flags: -C opt-level=0 -C lto=thin
|
||||||
|
//[thin1]compile-flags: -C opt-level=1 -C lto=thin
|
||||||
|
//[thin2]compile-flags: -C opt-level=2 -C lto=thin
|
||||||
|
//[thin3]compile-flags: -C opt-level=3 -C lto=thin
|
||||||
|
//[fat0]compile-flags: -C opt-level=0 -C lto=fat
|
||||||
|
//[fat1]compile-flags: -C opt-level=1 -C lto=fat
|
||||||
|
//[fat2]compile-flags: -C opt-level=2 -C lto=fat
|
||||||
|
//[fat3]compile-flags: -C opt-level=3 -C lto=fat
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
|
|
||||||
|
static SHARED: AtomicUsize = AtomicUsize::new(0);
|
||||||
|
|
||||||
|
assert_eq!(SHARED.fetch_add(0, Ordering::SeqCst), 0);
|
||||||
|
|
||||||
|
let old_hook = std::panic::take_hook();
|
||||||
|
|
||||||
|
std::panic::set_hook(Box::new(|_| { } )); // no-op on panic.
|
||||||
|
|
||||||
|
let handle = std::thread::spawn(|| {
|
||||||
|
struct Droppable;
|
||||||
|
impl Drop for Droppable {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
SHARED.fetch_add(1, Ordering::SeqCst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let _guard = Droppable;
|
||||||
|
None::<()>.expect("???");
|
||||||
|
});
|
||||||
|
|
||||||
|
let wait = handle.join();
|
||||||
|
|
||||||
|
// reinstate handler to ease observation of assertion failures.
|
||||||
|
std::panic::set_hook(old_hook);
|
||||||
|
|
||||||
|
assert!(wait.is_err());
|
||||||
|
|
||||||
|
assert_eq!(SHARED.fetch_add(0, Ordering::SeqCst), 1);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user