Add test for foreign double unwind
This commit is contained in:
parent
42b41da338
commit
0804e47792
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…
x
Reference in New Issue
Block a user