Add test for foreign double unwind
This commit is contained in:
parent
42b41da338
commit
0804e47792
3 changed files with 69 additions and 0 deletions
10
src/test/run-make-fulldeps/foreign-double-unwind/Makefile
Normal file
10
src/test/run-make-fulldeps/foreign-double-unwind/Makefile
Normal 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,$@,$<)
|
33
src/test/run-make-fulldeps/foreign-double-unwind/foo.cpp
Normal file
33
src/test/run-make-fulldeps/foreign-double-unwind/foo.cpp
Normal 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 (...)");
|
||||
}
|
||||
}
|
||||
}
|
26
src/test/run-make-fulldeps/foreign-double-unwind/foo.rs
Normal file
26
src/test/run-make-fulldeps/foreign-double-unwind/foo.rs
Normal 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) };
|
||||
}
|
Loading…
Add table
Reference in a new issue