Add test for foreign double unwind

This commit is contained in:
Gary Guo 2022-02-13 17:26:38 +00:00
parent 42b41da338
commit 0804e47792
3 changed files with 69 additions and 0 deletions

View file

@ -0,0 +1,10 @@
-include ../tools.mk
all: foo
$(call RUN,foo) | $(CGREP) -v unreachable
foo: foo.rs $(call NATIVE_STATICLIB,foo)
$(RUSTC) $< -lfoo $(EXTRARSCXXFLAGS)
$(TMPDIR)/libfoo.o: foo.cpp
$(call COMPILE_OBJ_CXX,$@,$<)

View file

@ -0,0 +1,33 @@
#include <cstdio>
#include <exception>
void println(const char* s) {
puts(s);
fflush(stdout);
}
struct outer_exception {};
struct inner_exception {};
extern "C" {
void throw_cxx_exception() {
if (std::uncaught_exception()) {
println("throwing inner C++ exception");
throw inner_exception();
} else {
println("throwing outer C++ exception");
throw outer_exception();
}
}
void cxx_catch_callback(void (*cb)()) {
try {
cb();
println("unreachable: callback returns");
} catch (outer_exception) {
println("unreachable: caught outer exception in catch (...)");
} catch (inner_exception) {
println("unreachable: caught inner exception in catch (...)");
}
}
}

View file

@ -0,0 +1,26 @@
// Tests that C++ double unwinding through Rust code will be properly guarded
// against instead of exhibiting undefined behaviour.
#![feature(c_unwind)]
extern "C-unwind" {
fn throw_cxx_exception();
fn cxx_catch_callback(cb: extern "C-unwind" fn());
}
struct ThrowOnDrop;
impl Drop for ThrowOnDrop {
fn drop(&mut self) {
unsafe { throw_cxx_exception() };
}
}
extern "C-unwind" fn test_double_unwind() {
let _a = ThrowOnDrop;
let _b = ThrowOnDrop;
}
fn main() {
unsafe { cxx_catch_callback(test_double_unwind) };
}