Add a test to check that swallowed Rust panics are dropped properly.

This commit is contained in:
Amanieu d'Antras 2019-12-29 23:23:40 +01:00
parent c15ad84519
commit 4361192112
2 changed files with 46 additions and 1 deletions

View File

@ -57,4 +57,21 @@ extern "C" {
throw;
}
}
void swallow_exception(void (*cb)()) {
try {
// Do a rethrow to ensure that the exception is only dropped once.
// This is necessary since we don't support copying exceptions.
try {
cb();
} catch (...) {
println("rethrowing Rust panic");
throw;
};
} catch (rust_panic e) {
assert(false && "shouldn't be able to catch a rust panic");
} catch (...) {
println("swallowing foreign exception in catch (...)");
}
}
}

View File

@ -4,7 +4,6 @@
// For linking libstdc++ on MinGW
#![cfg_attr(all(windows, target_env = "gnu"), feature(static_nobundle))]
#![feature(unwind_attributes)]
use std::panic::{catch_unwind, AssertUnwindSafe};
@ -20,6 +19,8 @@ fn drop(&mut self) {
extern "C" {
fn throw_cxx_exception();
fn swallow_exception(cb: extern "C" fn());
#[unwind(allowed)]
fn cxx_catch_callback(cb: extern "C" fn(), ok: *mut bool);
}
@ -60,7 +61,34 @@ extern "C" fn callback() {
assert!(cxx_ok);
}
fn check_exception_drop() {
static mut DROP_COUNT: usize = 0;
struct CountDrop;
impl Drop for CountDrop {
fn drop(&mut self) {
println!("CountDrop::drop");
unsafe {
DROP_COUNT += 1;
}
}
}
#[unwind(allowed)]
extern "C" fn callback() {
println!("throwing rust panic #2");
panic!(CountDrop);
}
unsafe {
swallow_exception(callback);
assert_eq!(DROP_COUNT, 1);
}
}
fn main() {
unsafe { throw_cxx_exception() };
throw_rust_panic();
check_exception_drop();
}