Skip to content

Rollup of 8 pull requests #137143

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 24 commits into from
Feb 17, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
4e36f46
core: Apply unsafe_op_in_unsafe_fn
ehuss Feb 13, 2025
e13928d
panic_abort: Apply unsafe_op_in_unsafe_fn
ehuss Feb 13, 2025
331911e
panic_unwind: Apply unsafe_op_in_unsafe_fn
ehuss Feb 13, 2025
0484d23
unwind: Apply unsafe_op_in_unsafe_fn
ehuss Feb 13, 2025
d5f0aa4
Fix safety of windows uwp functions
ehuss Feb 12, 2025
4f4ea35
std: Apply unsafe_op_in_unsafe_fn
ehuss Feb 13, 2025
80a7eb1
proc_macro: Apply unsafe_op_in_unsafe_fn
ehuss Feb 13, 2025
2830755
Bless miri tests after applying unsafe_op_in_unsafe_fn
ehuss Feb 13, 2025
6ec3cf9
Load all builtin targets at once instead of one by one
Urgau Feb 15, 2025
17071ff
Rework name_regions to not rely on reverse scc graph for non-member-c…
compiler-errors Feb 15, 2025
7e35729
Don't project into `NonNull` when dropping a `Box`
scottmcm Feb 16, 2025
6bdf340
add docs to cc-detect
Shourya742 Feb 14, 2025
f6c911a
add unit test for cc-detect
Shourya742 Feb 14, 2025
f396a31
Add an example for std::error::Error
ChrisDenton Feb 16, 2025
8ae3ca9
Fix test that relies on error language
ChrisDenton Feb 16, 2025
56f8f48
fix broken `x {doc, build} core`
onur-ozkan Feb 16, 2025
53b4c7c
Rollup merge of #136986 - ehuss:library-unsafe-fun, r=Noratrieb
matthiaskrgr Feb 16, 2025
34e789a
Rollup merge of #137012 - Shourya742:2025-02-14-doc-and-unit-test-cc-…
matthiaskrgr Feb 16, 2025
fc094a1
Rollup merge of #137072 - Urgau:check-cfg-load-builtins-at-once, r=No…
matthiaskrgr Feb 16, 2025
ea9c8d9
Rollup merge of #137102 - compiler-errors:name_regions2, r=oli-obk
matthiaskrgr Feb 16, 2025
b125096
Rollup merge of #137112 - scottmcm:box-drop-no-nonnull-project, r=oli…
matthiaskrgr Feb 16, 2025
f82764f
Rollup merge of #137114 - ChrisDenton:error, r=Noratrieb
matthiaskrgr Feb 16, 2025
7374439
Rollup merge of #137117 - ChrisDenton:error-lang, r=fmease,Noratrieb
matthiaskrgr Feb 16, 2025
e802a8c
Rollup merge of #137119 - onur-ozkan:fix-broken-core, r=jieyouxu
matthiaskrgr Feb 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
panic_unwind: Apply unsafe_op_in_unsafe_fn
  • Loading branch information
ehuss committed Feb 14, 2025
commit 331911e699f91bc890074fa42374c63dbea06c44
60 changes: 32 additions & 28 deletions library/panic_unwind/src/emcc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
40 changes: 21 additions & 19 deletions library/panic_unwind/src/gcc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
Expand Down
8 changes: 6 additions & 2 deletions library/panic_unwind/src/hermit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,16 @@ pub(crate) unsafe fn cleanup(_ptr: *mut u8) -> Box<dyn Any + Send> {
unsafe extern "C" {
fn __rust_abort() -> !;
}
__rust_abort();
unsafe {
__rust_abort();
}
}

pub(crate) unsafe fn panic(_data: Box<dyn Any + Send>) -> u32 {
unsafe extern "C" {
fn __rust_abort() -> !;
}
__rust_abort();
unsafe {
__rust_abort();
}
}
9 changes: 6 additions & 3 deletions library/panic_unwind/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -87,14 +88,16 @@ unsafe 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)
}
}
4 changes: 2 additions & 2 deletions library/panic_unwind/src/miri.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
78 changes: 43 additions & 35 deletions library/panic_unwind/src/seh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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(),
);
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()
}