about summary refs log tree commit diff
path: root/library/panic_unwind
diff options
context:
space:
mode:
Diffstat (limited to 'library/panic_unwind')
-rw-r--r--library/panic_unwind/src/emcc.rs64
-rw-r--r--library/panic_unwind/src/gcc.rs40
-rw-r--r--library/panic_unwind/src/hermit.rs12
-rw-r--r--library/panic_unwind/src/lib.rs11
-rw-r--r--library/panic_unwind/src/miri.rs6
-rw-r--r--library/panic_unwind/src/seh.rs86
6 files changed, 120 insertions, 99 deletions
diff --git a/library/panic_unwind/src/emcc.rs b/library/panic_unwind/src/emcc.rs
index 86906b46d66..1569c26c9de 100644
--- a/library/panic_unwind/src/emcc.rs
+++ b/library/panic_unwind/src/emcc.rs
@@ -21,7 +21,7 @@ struct TypeInfo {
 }
 unsafe impl Sync for TypeInfo {}
 
-extern "C" {
+unsafe extern "C" {
     // The leading `\x01` byte here is actually a magical signal to LLVM to
     // *not* apply any other mangling like prefixing with a `_` character.
     //
@@ -71,42 +71,46 @@ pub(crate) unsafe fn cleanup(ptr: *mut u8) -> Box<dyn Any + Send> {
         ptr: *mut u8,
         is_rust_panic: bool,
     }
-    let catch_data = &*(ptr as *mut CatchData);
+    unsafe {
+        let catch_data = &*(ptr as *mut CatchData);
 
-    let adjusted_ptr = __cxa_begin_catch(catch_data.ptr as *mut libc::c_void) as *mut Exception;
-    if !catch_data.is_rust_panic {
-        super::__rust_foreign_exception();
-    }
+        let adjusted_ptr = __cxa_begin_catch(catch_data.ptr as *mut libc::c_void) as *mut Exception;
+        if !catch_data.is_rust_panic {
+            super::__rust_foreign_exception();
+        }
 
-    let canary = (&raw const (*adjusted_ptr).canary).read();
-    if !ptr::eq(canary, &EXCEPTION_TYPE_INFO) {
-        super::__rust_foreign_exception();
-    }
+        let canary = (&raw const (*adjusted_ptr).canary).read();
+        if !ptr::eq(canary, &EXCEPTION_TYPE_INFO) {
+            super::__rust_foreign_exception();
+        }
 
-    let was_caught = (*adjusted_ptr).caught.swap(true, Ordering::Relaxed);
-    if was_caught {
-        // Since cleanup() isn't allowed to panic, we just abort instead.
-        intrinsics::abort();
+        let was_caught = (*adjusted_ptr).caught.swap(true, Ordering::Relaxed);
+        if was_caught {
+            // Since cleanup() isn't allowed to panic, we just abort instead.
+            intrinsics::abort();
+        }
+        let out = (*adjusted_ptr).data.take().unwrap();
+        __cxa_end_catch();
+        out
     }
-    let out = (*adjusted_ptr).data.take().unwrap();
-    __cxa_end_catch();
-    out
 }
 
 pub(crate) unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
-    let exception = __cxa_allocate_exception(mem::size_of::<Exception>()) as *mut Exception;
-    if exception.is_null() {
-        return uw::_URC_FATAL_PHASE1_ERROR as u32;
+    unsafe {
+        let exception = __cxa_allocate_exception(mem::size_of::<Exception>()) as *mut Exception;
+        if exception.is_null() {
+            return uw::_URC_FATAL_PHASE1_ERROR as u32;
+        }
+        ptr::write(
+            exception,
+            Exception {
+                canary: &EXCEPTION_TYPE_INFO,
+                caught: AtomicBool::new(false),
+                data: Some(data),
+            },
+        );
+        __cxa_throw(exception as *mut _, &EXCEPTION_TYPE_INFO, exception_cleanup);
     }
-    ptr::write(
-        exception,
-        Exception {
-            canary: &EXCEPTION_TYPE_INFO,
-            caught: AtomicBool::new(false),
-            data: Some(data),
-        },
-    );
-    __cxa_throw(exception as *mut _, &EXCEPTION_TYPE_INFO, exception_cleanup);
 }
 
 extern "C" fn exception_cleanup(ptr: *mut libc::c_void) -> *mut libc::c_void {
@@ -119,7 +123,7 @@ extern "C" fn exception_cleanup(ptr: *mut libc::c_void) -> *mut libc::c_void {
     }
 }
 
-extern "C" {
+unsafe extern "C" {
     fn __cxa_allocate_exception(thrown_size: libc::size_t) -> *mut libc::c_void;
     fn __cxa_begin_catch(thrown_exception: *mut libc::c_void) -> *mut libc::c_void;
     fn __cxa_end_catch();
diff --git a/library/panic_unwind/src/gcc.rs b/library/panic_unwind/src/gcc.rs
index e478f6c5fc8..5f95870069d 100644
--- a/library/panic_unwind/src/gcc.rs
+++ b/library/panic_unwind/src/gcc.rs
@@ -69,7 +69,7 @@ pub(crate) unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
         cause: data,
     });
     let exception_param = Box::into_raw(exception) as *mut uw::_Unwind_Exception;
-    return uw::_Unwind_RaiseException(exception_param) as u32;
+    return unsafe { uw::_Unwind_RaiseException(exception_param) as u32 };
 
     extern "C" fn exception_cleanup(
         _unwind_code: uw::_Unwind_Reason_Code,
@@ -83,26 +83,28 @@ pub(crate) unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
 }
 
 pub(crate) unsafe fn cleanup(ptr: *mut u8) -> Box<dyn Any + Send> {
-    let exception = ptr as *mut uw::_Unwind_Exception;
-    if (*exception).exception_class != RUST_EXCEPTION_CLASS {
-        uw::_Unwind_DeleteException(exception);
-        super::__rust_foreign_exception();
-    }
+    unsafe {
+        let exception = ptr as *mut uw::_Unwind_Exception;
+        if (*exception).exception_class != RUST_EXCEPTION_CLASS {
+            uw::_Unwind_DeleteException(exception);
+            super::__rust_foreign_exception();
+        }
 
-    let exception = exception.cast::<Exception>();
-    // Just access the canary field, avoid accessing the entire `Exception` as
-    // it can be a foreign Rust exception.
-    let canary = (&raw const (*exception).canary).read();
-    if !ptr::eq(canary, &CANARY) {
-        // A foreign Rust exception, treat it slightly differently from other
-        // foreign exceptions, because call into `_Unwind_DeleteException` will
-        // call into `__rust_drop_panic` which produces a confusing
-        // "Rust panic must be rethrown" message.
-        super::__rust_foreign_exception();
-    }
+        let exception = exception.cast::<Exception>();
+        // Just access the canary field, avoid accessing the entire `Exception` as
+        // it can be a foreign Rust exception.
+        let canary = (&raw const (*exception).canary).read();
+        if !ptr::eq(canary, &CANARY) {
+            // A foreign Rust exception, treat it slightly differently from other
+            // foreign exceptions, because call into `_Unwind_DeleteException` will
+            // call into `__rust_drop_panic` which produces a confusing
+            // "Rust panic must be rethrown" message.
+            super::__rust_foreign_exception();
+        }
 
-    let exception = Box::from_raw(exception as *mut Exception);
-    exception.cause
+        let exception = Box::from_raw(exception as *mut Exception);
+        exception.cause
+    }
 }
 
 // Rust's exception class identifier.  This is used by personality routines to
diff --git a/library/panic_unwind/src/hermit.rs b/library/panic_unwind/src/hermit.rs
index 7e08ad66577..8f4562d07fc 100644
--- a/library/panic_unwind/src/hermit.rs
+++ b/library/panic_unwind/src/hermit.rs
@@ -6,15 +6,19 @@ use alloc::boxed::Box;
 use core::any::Any;
 
 pub(crate) unsafe fn cleanup(_ptr: *mut u8) -> Box<dyn Any + Send> {
-    extern "C" {
+    unsafe extern "C" {
         fn __rust_abort() -> !;
     }
-    __rust_abort();
+    unsafe {
+        __rust_abort();
+    }
 }
 
 pub(crate) unsafe fn panic(_data: Box<dyn Any + Send>) -> u32 {
-    extern "C" {
+    unsafe extern "C" {
         fn __rust_abort() -> !;
     }
-    __rust_abort();
+    unsafe {
+        __rust_abort();
+    }
 }
diff --git a/library/panic_unwind/src/lib.rs b/library/panic_unwind/src/lib.rs
index d6828164195..1111c2009b3 100644
--- a/library/panic_unwind/src/lib.rs
+++ b/library/panic_unwind/src/lib.rs
@@ -27,6 +27,7 @@
 #![allow(internal_features)]
 #![cfg_attr(not(bootstrap), feature(cfg_emscripten_wasm_eh))]
 #![warn(unreachable_pub)]
+#![deny(unsafe_op_in_unsafe_fn)]
 
 use alloc::boxed::Box;
 use core::any::Any;
@@ -75,7 +76,7 @@ cfg_if::cfg_if! {
     }
 }
 
-extern "C" {
+unsafe extern "C" {
     /// Handler in std called when a panic object is dropped outside of
     /// `catch_unwind`.
     fn __rust_drop_panic() -> !;
@@ -87,14 +88,16 @@ extern "C" {
 #[rustc_std_internal_symbol]
 #[allow(improper_ctypes_definitions)]
 pub unsafe extern "C" fn __rust_panic_cleanup(payload: *mut u8) -> *mut (dyn Any + Send + 'static) {
-    Box::into_raw(imp::cleanup(payload))
+    unsafe { Box::into_raw(imp::cleanup(payload)) }
 }
 
 // Entry point for raising an exception, just delegates to the platform-specific
 // implementation.
 #[rustc_std_internal_symbol]
 pub unsafe fn __rust_start_panic(payload: &mut dyn PanicPayload) -> u32 {
-    let payload = Box::from_raw(payload.take_box());
+    unsafe {
+        let payload = Box::from_raw(payload.take_box());
 
-    imp::panic(payload)
+        imp::panic(payload)
+    }
 }
diff --git a/library/panic_unwind/src/miri.rs b/library/panic_unwind/src/miri.rs
index a86f0e91eef..d6d4af8218d 100644
--- a/library/panic_unwind/src/miri.rs
+++ b/library/panic_unwind/src/miri.rs
@@ -7,7 +7,7 @@ use core::any::Any;
 // Must be pointer-sized.
 type Payload = Box<Box<dyn Any + Send>>;
 
-extern "Rust" {
+unsafe extern "Rust" {
     /// Miri-provided extern function to begin unwinding.
     fn miri_start_unwind(payload: *mut u8) -> !;
 }
@@ -16,11 +16,11 @@ pub(crate) unsafe fn panic(payload: Box<dyn Any + Send>) -> u32 {
     // The payload we pass to `miri_start_unwind` will be exactly the argument we get
     // in `cleanup` below. So we just box it up once, to get something pointer-sized.
     let payload_box: Payload = Box::new(payload);
-    miri_start_unwind(Box::into_raw(payload_box) as *mut u8)
+    unsafe { miri_start_unwind(Box::into_raw(payload_box) as *mut u8) }
 }
 
 pub(crate) unsafe fn cleanup(payload_box: *mut u8) -> Box<dyn Any + Send> {
     // Recover the underlying `Box`.
-    let payload_box: Payload = Box::from_raw(payload_box as *mut _);
+    let payload_box: Payload = unsafe { Box::from_raw(payload_box as *mut _) };
     *payload_box
 }
diff --git a/library/panic_unwind/src/seh.rs b/library/panic_unwind/src/seh.rs
index 21bfe74e1a2..3a95b940221 100644
--- a/library/panic_unwind/src/seh.rs
+++ b/library/panic_unwind/src/seh.rs
@@ -135,7 +135,7 @@ mod imp {
     #[derive(Copy, Clone)]
     pub(super) struct ptr_t(u32);
 
-    extern "C" {
+    unsafe extern "C" {
         static __ImageBase: u8;
     }
 
@@ -229,7 +229,7 @@ static mut CATCHABLE_TYPE: _CatchableType = _CatchableType {
     copyFunction: ptr_t::null(),
 };
 
-extern "C" {
+unsafe extern "C" {
     // The leading `\x01` byte here is actually a magical signal to LLVM to
     // *not* apply any other mangling like prefixing with a `_` character.
     //
@@ -268,9 +268,11 @@ static mut TYPE_DESCRIPTOR: _TypeDescriptor = _TypeDescriptor {
 macro_rules! define_cleanup {
     ($abi:tt $abi2:tt) => {
         unsafe extern $abi fn exception_cleanup(e: *mut Exception) {
-            if let Exception { data: Some(b), .. } = e.read() {
-                drop(b);
-                super::__rust_drop_panic();
+            unsafe {
+                if let Exception { data: Some(b), .. } = e.read() {
+                    drop(b);
+                    super::__rust_drop_panic();
+                }
             }
         }
         unsafe extern $abi2 fn exception_copy(
@@ -322,45 +324,51 @@ pub(crate) unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
     //
     // In any case, we basically need to do something like this until we can
     // express more operations in statics (and we may never be able to).
-    atomic_store_seqcst(
-        (&raw mut THROW_INFO.pmfnUnwind).cast(),
-        ptr_t::new(exception_cleanup as *mut u8).raw(),
-    );
-    atomic_store_seqcst(
-        (&raw mut THROW_INFO.pCatchableTypeArray).cast(),
-        ptr_t::new((&raw mut CATCHABLE_TYPE_ARRAY).cast()).raw(),
-    );
-    atomic_store_seqcst(
-        (&raw mut CATCHABLE_TYPE_ARRAY.arrayOfCatchableTypes[0]).cast(),
-        ptr_t::new((&raw mut CATCHABLE_TYPE).cast()).raw(),
-    );
-    atomic_store_seqcst(
-        (&raw mut CATCHABLE_TYPE.pType).cast(),
-        ptr_t::new((&raw mut TYPE_DESCRIPTOR).cast()).raw(),
-    );
-    atomic_store_seqcst(
-        (&raw mut CATCHABLE_TYPE.copyFunction).cast(),
-        ptr_t::new(exception_copy as *mut u8).raw(),
-    );
-
-    extern "system-unwind" {
+    unsafe {
+        atomic_store_seqcst(
+            (&raw mut THROW_INFO.pmfnUnwind).cast(),
+            ptr_t::new(exception_cleanup as *mut u8).raw(),
+        );
+        atomic_store_seqcst(
+            (&raw mut THROW_INFO.pCatchableTypeArray).cast(),
+            ptr_t::new((&raw mut CATCHABLE_TYPE_ARRAY).cast()).raw(),
+        );
+        atomic_store_seqcst(
+            (&raw mut CATCHABLE_TYPE_ARRAY.arrayOfCatchableTypes[0]).cast(),
+            ptr_t::new((&raw mut CATCHABLE_TYPE).cast()).raw(),
+        );
+        atomic_store_seqcst(
+            (&raw mut CATCHABLE_TYPE.pType).cast(),
+            ptr_t::new((&raw mut TYPE_DESCRIPTOR).cast()).raw(),
+        );
+        atomic_store_seqcst(
+            (&raw mut CATCHABLE_TYPE.copyFunction).cast(),
+            ptr_t::new(exception_copy as *mut u8).raw(),
+        );
+    }
+
+    unsafe extern "system-unwind" {
         fn _CxxThrowException(pExceptionObject: *mut c_void, pThrowInfo: *mut u8) -> !;
     }
 
-    _CxxThrowException(throw_ptr, (&raw mut THROW_INFO) as *mut _);
+    unsafe {
+        _CxxThrowException(throw_ptr, (&raw mut THROW_INFO) as *mut _);
+    }
 }
 
 pub(crate) unsafe fn cleanup(payload: *mut u8) -> Box<dyn Any + Send> {
-    // A null payload here means that we got here from the catch (...) of
-    // __rust_try. This happens when a non-Rust foreign exception is caught.
-    if payload.is_null() {
-        super::__rust_foreign_exception();
-    }
-    let exception = payload as *mut Exception;
-    let canary = (&raw const (*exception).canary).read();
-    if !core::ptr::eq(canary, &raw const TYPE_DESCRIPTOR) {
-        // A foreign Rust exception.
-        super::__rust_foreign_exception();
+    unsafe {
+        // A null payload here means that we got here from the catch (...) of
+        // __rust_try. This happens when a non-Rust foreign exception is caught.
+        if payload.is_null() {
+            super::__rust_foreign_exception();
+        }
+        let exception = payload as *mut Exception;
+        let canary = (&raw const (*exception).canary).read();
+        if !core::ptr::eq(canary, &raw const TYPE_DESCRIPTOR) {
+            // A foreign Rust exception.
+            super::__rust_foreign_exception();
+        }
+        (*exception).data.take().unwrap()
     }
-    (*exception).data.take().unwrap()
 }