From 43611921120e2df3383f99b42bf060a6be28f23e Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Sun, 29 Dec 2019 23:23:40 +0100 Subject: [PATCH] Add a test to check that swallowed Rust panics are dropped properly. --- .../foreign-exceptions/foo.cpp | 17 +++++++++++ .../foreign-exceptions/foo.rs | 30 ++++++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/test/run-make-fulldeps/foreign-exceptions/foo.cpp b/src/test/run-make-fulldeps/foreign-exceptions/foo.cpp index b0fd65f88e7de..ef5cd74c65283 100644 --- a/src/test/run-make-fulldeps/foreign-exceptions/foo.cpp +++ b/src/test/run-make-fulldeps/foreign-exceptions/foo.cpp @@ -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 (...)"); + } + } } diff --git a/src/test/run-make-fulldeps/foreign-exceptions/foo.rs b/src/test/run-make-fulldeps/foreign-exceptions/foo.rs index 399c78f8d2d02..d9818dffc502b 100644 --- a/src/test/run-make-fulldeps/foreign-exceptions/foo.rs +++ b/src/test/run-make-fulldeps/foreign-exceptions/foo.rs @@ -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 @@ impl<'a> Drop for DropCheck<'a> { 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 @@ fn throw_rust_panic() { 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(); }