about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-08-28 01:20:17 +0000
committerbors <bors@rust-lang.org>2020-08-28 01:20:17 +0000
commit41aaa90c67cdb04cac7427756891ad04c3e0bebf (patch)
treed7cb34d5fc429af98cde7a794a1ab4eb22eb99cd /src/test
parent2aa741a9faf8519d3af98aba610677c8d2bc84a5 (diff)
parent239f833ed1842ce7ce5c9989871a9ce9b1ea3546 (diff)
downloadrust-41aaa90c67cdb04cac7427756891ad04c3e0bebf.tar.gz
rust-41aaa90c67cdb04cac7427756891ad04c3e0bebf.zip
Auto merge of #70212 - Amanieu:catch_foreign, r=Mark-Simulacrum
Abort when foreign exceptions are caught by catch_unwind

Prior to this PR, foreign exceptions were not caught by catch_unwind, and instead passed through invisibly. This represented a painful soundness hole in some libraries ([take_mut](https://github.com/Sgeo/take_mut/blob/master/src/lib.rs#L37)), which relied on `catch_unwind` to handle all possible exit paths from a closure.

With this PR, foreign exceptions are now caught by `catch_unwind` and will trigger an abort since catching foreign exceptions is currently UB according to the latest proposals by the FFI unwind project group.

cc @rust-lang/wg-ffi-unwind
Diffstat (limited to 'src/test')
-rw-r--r--src/test/compile-fail/auxiliary/panic-runtime-lang-items.rs2
-rw-r--r--src/test/run-make-fulldeps/foreign-exceptions/foo.cpp6
-rw-r--r--src/test/run-make-fulldeps/foreign-exceptions/foo.rs21
-rw-r--r--src/test/run-make-fulldeps/issue-69368/a.rs5
-rw-r--r--src/test/ui/consts/const-eval/const_panic_libcore_main.rs2
-rw-r--r--src/test/ui/macros/macro-comma-behavior.core.stderr14
-rw-r--r--src/test/ui/macros/macro-comma-behavior.rs1
-rw-r--r--src/test/ui/macros/macro-comma-behavior.std.stderr20
-rw-r--r--src/test/ui/no_owned_box_lang_item.rs1
-rw-r--r--src/test/ui/panic-runtime/auxiliary/panic-runtime-lang-items.rs2
-rw-r--r--src/test/ui/range/issue-54505-no-std.rs3
-rw-r--r--src/test/ui/range/issue-54505-no-std.stderr12
12 files changed, 51 insertions, 38 deletions
diff --git a/src/test/compile-fail/auxiliary/panic-runtime-lang-items.rs b/src/test/compile-fail/auxiliary/panic-runtime-lang-items.rs
index 3e5cdad7ab9..b9ef2f32941 100644
--- a/src/test/compile-fail/auxiliary/panic-runtime-lang-items.rs
+++ b/src/test/compile-fail/auxiliary/panic-runtime-lang-items.rs
@@ -11,3 +11,5 @@ use core::panic::PanicInfo;
 fn panic_impl(info: &PanicInfo) -> ! { loop {} }
 #[lang = "eh_personality"]
 fn eh_personality() {}
+#[lang = "eh_catch_typeinfo"]
+static EH_CATCH_TYPEINFO: u8 = 0;
diff --git a/src/test/run-make-fulldeps/foreign-exceptions/foo.cpp b/src/test/run-make-fulldeps/foreign-exceptions/foo.cpp
index b0fd65f88e7..8182021a2cc 100644
--- a/src/test/run-make-fulldeps/foreign-exceptions/foo.cpp
+++ b/src/test/run-make-fulldeps/foreign-exceptions/foo.cpp
@@ -23,15 +23,15 @@ struct drop_check {
 extern "C" {
     void rust_catch_callback(void (*cb)(), bool* rust_ok);
 
-    static void callback() {
+    void throw_cxx_exception() {
         println("throwing C++ exception");
         throw exception();
     }
 
-    void throw_cxx_exception() {
+    void test_cxx_exception() {
         bool rust_ok = false;
         try {
-            rust_catch_callback(callback, &rust_ok);
+            rust_catch_callback(throw_cxx_exception, &rust_ok);
             assert(false && "unreachable");
         } catch (exception e) {
             println("caught C++ exception");
diff --git a/src/test/run-make-fulldeps/foreign-exceptions/foo.rs b/src/test/run-make-fulldeps/foreign-exceptions/foo.rs
index 9c2045c8c89..b5c8c1962a8 100644
--- a/src/test/run-make-fulldeps/foreign-exceptions/foo.rs
+++ b/src/test/run-make-fulldeps/foreign-exceptions/foo.rs
@@ -1,5 +1,5 @@
-// Tests that C++ exceptions can unwind through Rust code, run destructors and
-// are ignored by catch_unwind. Also tests that Rust panics can unwind through
+// Tests that C++ exceptions can unwind through Rust code run destructors and
+// are caught by catch_unwind. Also tests that Rust panics can unwind through
 // C++ code.
 
 // For linking libstdc++ on MinGW
@@ -17,7 +17,7 @@ impl<'a> Drop for DropCheck<'a> {
 }
 
 extern "C" {
-    fn throw_cxx_exception();
+    fn test_cxx_exception();
 
     #[unwind(allowed)]
     fn cxx_catch_callback(cb: extern "C" fn(), ok: *mut bool);
@@ -26,15 +26,12 @@ extern "C" {
 #[no_mangle]
 #[unwind(allowed)]
 extern "C" fn rust_catch_callback(cb: extern "C" fn(), rust_ok: &mut bool) {
-    let _caught_unwind = catch_unwind(AssertUnwindSafe(|| {
-        let _drop = DropCheck(rust_ok);
-        cb();
-        unreachable!("should have unwound instead of returned");
-    }));
-    unreachable!("catch_unwind should not have caught foreign exception");
+    let _drop = DropCheck(rust_ok);
+    cb();
+    unreachable!("should have unwound instead of returned");
 }
 
-fn throw_rust_panic() {
+fn test_rust_panic() {
     #[unwind(allowed)]
     extern "C" fn callback() {
         println!("throwing rust panic");
@@ -60,6 +57,6 @@ fn throw_rust_panic() {
 }
 
 fn main() {
-    unsafe { throw_cxx_exception() };
-    throw_rust_panic();
+    unsafe { test_cxx_exception() };
+    test_rust_panic();
 }
diff --git a/src/test/run-make-fulldeps/issue-69368/a.rs b/src/test/run-make-fulldeps/issue-69368/a.rs
index 726db874637..7d339c5a5da 100644
--- a/src/test/run-make-fulldeps/issue-69368/a.rs
+++ b/src/test/run-make-fulldeps/issue-69368/a.rs
@@ -14,3 +14,8 @@ pub fn panic_handler(_: &core::panic::PanicInfo) -> ! {
 extern "C" fn __rust_drop_panic() -> ! {
     loop {}
 }
+
+#[no_mangle]
+extern "C" fn __rust_foreign_exception() -> ! {
+    loop {}
+}
diff --git a/src/test/ui/consts/const-eval/const_panic_libcore_main.rs b/src/test/ui/consts/const-eval/const_panic_libcore_main.rs
index 6b86feb5921..6b03e847def 100644
--- a/src/test/ui/consts/const-eval/const_panic_libcore_main.rs
+++ b/src/test/ui/consts/const-eval/const_panic_libcore_main.rs
@@ -17,6 +17,8 @@ const X: () = unimplemented!();
 
 #[lang = "eh_personality"]
 fn eh() {}
+#[lang = "eh_catch_typeinfo"]
+static EH_CATCH_TYPEINFO: u8 = 0;
 
 #[panic_handler]
 fn panic(_info: &PanicInfo) -> ! {
diff --git a/src/test/ui/macros/macro-comma-behavior.core.stderr b/src/test/ui/macros/macro-comma-behavior.core.stderr
index 83a88ab3bd9..dd0cac659fd 100644
--- a/src/test/ui/macros/macro-comma-behavior.core.stderr
+++ b/src/test/ui/macros/macro-comma-behavior.core.stderr
@@ -1,41 +1,41 @@
 error: 1 positional argument in format string, but no arguments were given
-  --> $DIR/macro-comma-behavior.rs:20:23
+  --> $DIR/macro-comma-behavior.rs:21:23
    |
 LL |     assert_eq!(1, 1, "{}",);
    |                       ^^
 
 error: 1 positional argument in format string, but no arguments were given
-  --> $DIR/macro-comma-behavior.rs:23:23
+  --> $DIR/macro-comma-behavior.rs:24:23
    |
 LL |     assert_ne!(1, 2, "{}",);
    |                       ^^
 
 error: 1 positional argument in format string, but no arguments were given
-  --> $DIR/macro-comma-behavior.rs:29:29
+  --> $DIR/macro-comma-behavior.rs:30:29
    |
 LL |     debug_assert_eq!(1, 1, "{}",);
    |                             ^^
 
 error: 1 positional argument in format string, but no arguments were given
-  --> $DIR/macro-comma-behavior.rs:32:29
+  --> $DIR/macro-comma-behavior.rs:33:29
    |
 LL |     debug_assert_ne!(1, 2, "{}",);
    |                             ^^
 
 error: 1 positional argument in format string, but no arguments were given
-  --> $DIR/macro-comma-behavior.rs:53:19
+  --> $DIR/macro-comma-behavior.rs:54:19
    |
 LL |     format_args!("{}",);
    |                   ^^
 
 error: 1 positional argument in format string, but no arguments were given
-  --> $DIR/macro-comma-behavior.rs:71:21
+  --> $DIR/macro-comma-behavior.rs:72:21
    |
 LL |     unimplemented!("{}",);
    |                     ^^
 
 error: 1 positional argument in format string, but no arguments were given
-  --> $DIR/macro-comma-behavior.rs:80:24
+  --> $DIR/macro-comma-behavior.rs:81:24
    |
 LL |             write!(f, "{}",)?;
    |                        ^^
diff --git a/src/test/ui/macros/macro-comma-behavior.rs b/src/test/ui/macros/macro-comma-behavior.rs
index 04714c65b5c..0bfe0683078 100644
--- a/src/test/ui/macros/macro-comma-behavior.rs
+++ b/src/test/ui/macros/macro-comma-behavior.rs
@@ -9,6 +9,7 @@
 #[cfg(std)] use std::fmt;
 #[cfg(core)] use core::fmt;
 #[cfg(core)] #[lang = "eh_personality"] fn eh_personality() {}
+#[cfg(core)] #[lang = "eh_catch_typeinfo"] static EH_CATCH_TYPEINFO: u8 = 0;
 #[cfg(core)] #[lang = "panic_impl"] fn panic_impl(panic: &core::panic::PanicInfo) -> ! { loop {} }
 
 // (see documentation of the similarly-named test in run-pass)
diff --git a/src/test/ui/macros/macro-comma-behavior.std.stderr b/src/test/ui/macros/macro-comma-behavior.std.stderr
index 26445f2c5c5..4372d89fbf5 100644
--- a/src/test/ui/macros/macro-comma-behavior.std.stderr
+++ b/src/test/ui/macros/macro-comma-behavior.std.stderr
@@ -1,59 +1,59 @@
 error: 1 positional argument in format string, but no arguments were given
-  --> $DIR/macro-comma-behavior.rs:20:23
+  --> $DIR/macro-comma-behavior.rs:21:23
    |
 LL |     assert_eq!(1, 1, "{}",);
    |                       ^^
 
 error: 1 positional argument in format string, but no arguments were given
-  --> $DIR/macro-comma-behavior.rs:23:23
+  --> $DIR/macro-comma-behavior.rs:24:23
    |
 LL |     assert_ne!(1, 2, "{}",);
    |                       ^^
 
 error: 1 positional argument in format string, but no arguments were given
-  --> $DIR/macro-comma-behavior.rs:29:29
+  --> $DIR/macro-comma-behavior.rs:30:29
    |
 LL |     debug_assert_eq!(1, 1, "{}",);
    |                             ^^
 
 error: 1 positional argument in format string, but no arguments were given
-  --> $DIR/macro-comma-behavior.rs:32:29
+  --> $DIR/macro-comma-behavior.rs:33:29
    |
 LL |     debug_assert_ne!(1, 2, "{}",);
    |                             ^^
 
 error: 1 positional argument in format string, but no arguments were given
-  --> $DIR/macro-comma-behavior.rs:37:18
+  --> $DIR/macro-comma-behavior.rs:38:18
    |
 LL |         eprint!("{}",);
    |                  ^^
 
 error: 1 positional argument in format string, but no arguments were given
-  --> $DIR/macro-comma-behavior.rs:49:18
+  --> $DIR/macro-comma-behavior.rs:50:18
    |
 LL |         format!("{}",);
    |                  ^^
 
 error: 1 positional argument in format string, but no arguments were given
-  --> $DIR/macro-comma-behavior.rs:53:19
+  --> $DIR/macro-comma-behavior.rs:54:19
    |
 LL |     format_args!("{}",);
    |                   ^^
 
 error: 1 positional argument in format string, but no arguments were given
-  --> $DIR/macro-comma-behavior.rs:60:17
+  --> $DIR/macro-comma-behavior.rs:61:17
    |
 LL |         print!("{}",);
    |                 ^^
 
 error: 1 positional argument in format string, but no arguments were given
-  --> $DIR/macro-comma-behavior.rs:71:21
+  --> $DIR/macro-comma-behavior.rs:72:21
    |
 LL |     unimplemented!("{}",);
    |                     ^^
 
 error: 1 positional argument in format string, but no arguments were given
-  --> $DIR/macro-comma-behavior.rs:80:24
+  --> $DIR/macro-comma-behavior.rs:81:24
    |
 LL |             write!(f, "{}",)?;
    |                        ^^
diff --git a/src/test/ui/no_owned_box_lang_item.rs b/src/test/ui/no_owned_box_lang_item.rs
index 58e45ff73a5..bef630d826c 100644
--- a/src/test/ui/no_owned_box_lang_item.rs
+++ b/src/test/ui/no_owned_box_lang_item.rs
@@ -12,4 +12,5 @@ fn main() {
 }
 
 #[lang = "eh_personality"] extern fn eh_personality() {}
+#[lang = "eh_catch_typeinfo"] static EH_CATCH_TYPEINFO: u8 = 0;
 #[lang = "panic_impl"] fn panic_impl(panic: &PanicInfo) -> ! { loop {} }
diff --git a/src/test/ui/panic-runtime/auxiliary/panic-runtime-lang-items.rs b/src/test/ui/panic-runtime/auxiliary/panic-runtime-lang-items.rs
index 3e5cdad7ab9..b9ef2f32941 100644
--- a/src/test/ui/panic-runtime/auxiliary/panic-runtime-lang-items.rs
+++ b/src/test/ui/panic-runtime/auxiliary/panic-runtime-lang-items.rs
@@ -11,3 +11,5 @@ use core::panic::PanicInfo;
 fn panic_impl(info: &PanicInfo) -> ! { loop {} }
 #[lang = "eh_personality"]
 fn eh_personality() {}
+#[lang = "eh_catch_typeinfo"]
+static EH_CATCH_TYPEINFO: u8 = 0;
diff --git a/src/test/ui/range/issue-54505-no-std.rs b/src/test/ui/range/issue-54505-no-std.rs
index c6a3cc346fc..f5d5823e468 100644
--- a/src/test/ui/range/issue-54505-no-std.rs
+++ b/src/test/ui/range/issue-54505-no-std.rs
@@ -14,6 +14,9 @@ use core::ops::RangeBounds;
 #[cfg(any(not(target_arch = "wasm32"), target_os = "emscripten"))]
 #[lang = "eh_personality"]
 extern fn eh_personality() {}
+#[cfg(target_os = "emscripten")]
+#[lang = "eh_catch_typeinfo"]
+static EH_CATCH_TYPEINFO: u8 = 0;
 
 
 // take a reference to any built-in range
diff --git a/src/test/ui/range/issue-54505-no-std.stderr b/src/test/ui/range/issue-54505-no-std.stderr
index 90934061132..5537ed45767 100644
--- a/src/test/ui/range/issue-54505-no-std.stderr
+++ b/src/test/ui/range/issue-54505-no-std.stderr
@@ -1,7 +1,7 @@
 error: `#[panic_handler]` function required, but not found
 
 error[E0308]: mismatched types
-  --> $DIR/issue-54505-no-std.rs:24:16
+  --> $DIR/issue-54505-no-std.rs:27:16
    |
 LL |     take_range(0..1);
    |                ^^^^
@@ -13,7 +13,7 @@ LL |     take_range(0..1);
                  found struct `core::ops::Range<{integer}>`
 
 error[E0308]: mismatched types
-  --> $DIR/issue-54505-no-std.rs:29:16
+  --> $DIR/issue-54505-no-std.rs:32:16
    |
 LL |     take_range(1..);
    |                ^^^
@@ -25,7 +25,7 @@ LL |     take_range(1..);
                  found struct `core::ops::RangeFrom<{integer}>`
 
 error[E0308]: mismatched types
-  --> $DIR/issue-54505-no-std.rs:34:16
+  --> $DIR/issue-54505-no-std.rs:37:16
    |
 LL |     take_range(..);
    |                ^^
@@ -37,7 +37,7 @@ LL |     take_range(..);
                  found struct `core::ops::RangeFull`
 
 error[E0308]: mismatched types
-  --> $DIR/issue-54505-no-std.rs:39:16
+  --> $DIR/issue-54505-no-std.rs:42:16
    |
 LL |     take_range(0..=1);
    |                ^^^^^
@@ -49,7 +49,7 @@ LL |     take_range(0..=1);
                  found struct `core::ops::RangeInclusive<{integer}>`
 
 error[E0308]: mismatched types
-  --> $DIR/issue-54505-no-std.rs:44:16
+  --> $DIR/issue-54505-no-std.rs:47:16
    |
 LL |     take_range(..5);
    |                ^^^
@@ -61,7 +61,7 @@ LL |     take_range(..5);
                  found struct `core::ops::RangeTo<{integer}>`
 
 error[E0308]: mismatched types
-  --> $DIR/issue-54505-no-std.rs:49:16
+  --> $DIR/issue-54505-no-std.rs:52:16
    |
 LL |     take_range(..=42);
    |                ^^^^^