Skip to content
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

rename 'try' intrinsic to 'catch_unwind' #121598

Merged
merged 2 commits into from
Feb 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use rustc_middle::ty::layout::{HasParamEnv, ValidityRequirement};
use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
use rustc_middle::ty::GenericArgsRef;
use rustc_span::source_map::Spanned;
use rustc_span::symbol::{kw, sym, Symbol};
use rustc_span::symbol::{sym, Symbol};

pub(crate) use self::llvm::codegen_llvm_intrinsic_call;
use crate::prelude::*;
Expand Down Expand Up @@ -1132,7 +1132,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
ret.write_cvalue(fx, val);
}

kw::Try => {
sym::catch_unwind => {
intrinsic_args!(fx, args => (f, data, catch_fn); intrinsic);
let f = f.load_scalar(fx);
let data = data.load_scalar(fx);
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use rustc_middle::ty::{self, Instance, Ty};
use rustc_middle::ty::layout::LayoutOf;
#[cfg(feature="master")]
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt};
use rustc_span::{Span, Symbol, symbol::kw, sym};
use rustc_span::{Span, Symbol, sym};
use rustc_target::abi::HasDataLayout;
use rustc_target::abi::call::{ArgAbi, FnAbi, PassMode};
use rustc_target::spec::PanicStrategy;
Expand Down Expand Up @@ -129,7 +129,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
let res = self.context.new_call(None, builtin, &[a]);
self.icmp(IntPredicate::IntEQ, res, self.const_i32(0))
}
kw::Try => {
sym::catch_unwind => {
try_intrinsic(
self,
args[0].immediate(),
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_codegen_llvm/src/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use rustc_hir as hir;
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, LayoutOf};
use rustc_middle::ty::{self, GenericArgsRef, Ty};
use rustc_middle::{bug, span_bug};
use rustc_span::{sym, symbol::kw, Span, Symbol};
use rustc_span::{sym, Span, Symbol};
use rustc_target::abi::{self, Align, HasDataLayout, Primitive};
use rustc_target::spec::{HasTargetSpec, PanicStrategy};

Expand Down Expand Up @@ -133,8 +133,8 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
}
sym::unlikely => self
.call_intrinsic("llvm.expect.i1", &[args[0].immediate(), self.const_bool(false)]),
kw::Try => {
try_intrinsic(
sym::catch_unwind => {
catch_unwind_intrinsic(
self,
args[0].immediate(),
args[1].immediate(),
Expand Down Expand Up @@ -457,7 +457,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
}
}

fn try_intrinsic<'ll>(
fn catch_unwind_intrinsic<'ll>(
bx: &mut Builder<'_, 'll, '_>,
try_func: &'ll Value,
data: &'ll Value,
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/check/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use rustc_hir as hir;
use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_span::def_id::LocalDefId;
use rustc_span::symbol::{kw, sym};
use rustc_span::symbol::sym;
use rustc_span::{Span, Symbol};
use rustc_target::spec::abi::Abi;

Expand Down Expand Up @@ -445,7 +445,7 @@ pub fn check_intrinsic_type(
)
}

kw::Try => {
sym::catch_unwind => {
let mut_u8 = Ty::new_mut_ptr(tcx, tcx.types.u8);
let try_fn_ty = ty::Binder::dummy(tcx.mk_fn_sig(
[mut_u8],
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,7 @@ symbols! {
call_once,
caller_location,
capture_disjoint_fields,
catch_unwind,
cause,
cdylib,
ceilf32,
Expand Down
25 changes: 18 additions & 7 deletions library/core/src/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
unsafe { crate::ptr::drop_in_place(to_drop) }
}

#[cfg(bootstrap)]
pub use self::r#try as catch_unwind;

extern "rust-intrinsic" {
// N.B., these intrinsics take raw pointers because they mutate aliased
// memory, which is not valid for either `&` or `&mut`.
Expand Down Expand Up @@ -2382,16 +2385,24 @@ extern "rust-intrinsic" {
#[rustc_nounwind]
pub fn variant_count<T>() -> usize;

/// Rust's "try catch" construct which invokes the function pointer `try_fn`
/// with the data pointer `data`.
///
/// The third argument is a function called if a panic occurs. This function
/// takes the data pointer and a pointer to the target-specific exception
/// object that was caught. For more information see the compiler's
/// source as well as std's catch implementation.
/// Rust's "try catch" construct for unwinding. Invokes the function pointer `try_fn` with the
/// data pointer `data`, and calls `catch_fn` if unwinding occurs while `try_fn` runs.
///
/// `catch_fn` must not unwind.
///
/// The third argument is a function called if an unwind occurs (both Rust unwinds and foreign
/// unwinds). This function takes the data pointer and a pointer to the target-specific
/// exception object that was caught. For more information, see the compiler's source as well as
/// std's `catch_unwind` implementation.
///
/// The stable version of this intrinsic is `std::panic::catch_unwind`.
#[rustc_nounwind]
#[cfg(not(bootstrap))]
pub fn catch_unwind(try_fn: fn(*mut u8), data: *mut u8, catch_fn: fn(*mut u8, *mut u8)) -> i32;

/// For bootstrap only, see `catch_unwind`.
#[rustc_nounwind]
#[cfg(bootstrap)]
pub fn r#try(try_fn: fn(*mut u8), data: *mut u8, catch_fn: fn(*mut u8, *mut u8)) -> i32;

/// Emits a `!nontemporal` store according to LLVM (see their docs).
Expand Down
6 changes: 3 additions & 3 deletions library/panic_unwind/src/miri.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ type Payload = Box<Box<dyn Any + Send>>;

extern "Rust" {
/// Miri-provided extern function to begin unwinding.
fn miri_start_panic(payload: *mut u8) -> !;
fn miri_start_unwind(payload: *mut u8) -> !;
}

pub unsafe fn panic(payload: Box<dyn Any + Send>) -> u32 {
// The payload we pass to `miri_start_panic` will be exactly the argument we get
// 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_panic(Box::into_raw(payload_box) as *mut u8)
miri_start_unwind(Box::into_raw(payload_box) as *mut u8)
}

pub unsafe fn cleanup(payload_box: *mut u8) -> Box<dyn Any + Send> {
Expand Down
8 changes: 4 additions & 4 deletions library/std/src/panicking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -508,12 +508,12 @@ pub unsafe fn r#try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any + Send>>
// Access to the union's fields: this is `std` and we know that the `r#try`
// intrinsic fills in the `r` or `p` union field based on its return value.
//
// The call to `intrinsics::r#try` is made safe by:
// The call to `intrinsics::catch_unwind` is made safe by:
// - `do_call`, the first argument, can be called with the initial `data_ptr`.
// - `do_catch`, the second argument, can be called with the `data_ptr` as well.
// See their safety preconditions for more information
unsafe {
return if intrinsics::r#try(do_call::<F, R>, data_ptr, do_catch::<F, R>) == 0 {
return if intrinsics::catch_unwind(do_call::<F, R>, data_ptr, do_catch::<F, R>) == 0 {
Ok(ManuallyDrop::into_inner(data.r))
} else {
Err(ManuallyDrop::into_inner(data.p))
Expand All @@ -540,7 +540,7 @@ pub unsafe fn r#try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any + Send>>
// Its must contains a valid `f` (type: F) value that can be use to fill
// `data.r`.
//
// This function cannot be marked as `unsafe` because `intrinsics::r#try`
// This function cannot be marked as `unsafe` because `intrinsics::catch_unwind`
// expects normal function pointers.
#[inline]
fn do_call<F: FnOnce() -> R, R>(data: *mut u8) {
Expand All @@ -562,7 +562,7 @@ pub unsafe fn r#try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any + Send>>
// Since this uses `cleanup` it also hinges on a correct implementation of
// `__rustc_panic_cleanup`.
//
// This function cannot be marked as `unsafe` because `intrinsics::r#try`
// This function cannot be marked as `unsafe` because `intrinsics::catch_unwind`
// expects normal function pointers.
#[inline]
#[rustc_nounwind] // `intrinsic::r#try` requires catch fn to be nounwind
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/src/concurrency/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ pub struct Thread<'mir, 'tcx> {
join_status: ThreadJoinStatus,

/// Stack of active panic payloads for the current thread. Used for storing
/// the argument of the call to `miri_start_panic` (the panic payload) when unwinding.
/// the argument of the call to `miri_start_unwind` (the panic payload) when unwinding.
/// This is pointer-sized, and matches the `Payload` type in `src/libpanic_unwind/miri.rs`.
///
/// In real unwinding, the payload gets passed as an argument to the landing pad,
Expand Down
6 changes: 3 additions & 3 deletions src/tools/miri/src/shims/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
let ret = match ret {
None =>
match link_name.as_str() {
"miri_start_panic" => {
// `check_shim` happens inside `handle_miri_start_panic`.
this.handle_miri_start_panic(abi, link_name, args, unwind)?;
"miri_start_unwind" => {
// `check_shim` happens inside `handle_miri_start_unwind`.
this.handle_miri_start_unwind(abi, link_name, args, unwind)?;
return Ok(None);
}
// This matches calls to the foreign item `panic_impl`.
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/src/shims/intrinsics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {

// Some intrinsics are special and need the "ret".
match intrinsic_name {
"try" => return this.handle_try(args, dest, ret),
"catch_unwind" => return this.handle_catch_unwind(args, dest, ret),
_ => {}
}

Expand Down
16 changes: 8 additions & 8 deletions src/tools/miri/src/shims/panic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
//! The core pieces of the runtime are:
//! - An implementation of `__rust_maybe_catch_panic` that pushes the invoked stack frame with
//! some extra metadata derived from the panic-catching arguments of `__rust_maybe_catch_panic`.
//! - A hack in `libpanic_unwind` that calls the `miri_start_panic` intrinsic instead of the
//! - A hack in `libpanic_unwind` that calls the `miri_start_unwind` intrinsic instead of the
//! target-native panic runtime. (This lives in the rustc repo.)
//! - An implementation of `miri_start_panic` that stores its argument (the panic payload), and then
//! - An implementation of `miri_start_unwind` that stores its argument (the panic payload), and then
//! immediately returns, but on the *unwind* edge (not the normal return edge), thus initiating unwinding.
//! - A hook executed each time a frame is popped, such that if the frame pushed by `__rust_maybe_catch_panic`
//! gets popped *during unwinding*, we take the panic payload and store it according to the extra
Expand Down Expand Up @@ -44,9 +44,9 @@ impl VisitProvenance for CatchUnwindData<'_> {

impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
/// Handles the special `miri_start_panic` intrinsic, which is called
/// Handles the special `miri_start_unwind` intrinsic, which is called
/// by libpanic_unwind to delegate the actual unwinding process to Miri.
fn handle_miri_start_panic(
fn handle_miri_start_unwind(
&mut self,
abi: Abi,
link_name: Symbol,
Expand All @@ -55,7 +55,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();

trace!("miri_start_panic: {:?}", this.frame().instance);
trace!("miri_start_unwind: {:?}", this.frame().instance);

// Get the raw pointer stored in arg[0] (the panic payload).
let [payload] = this.check_shim(abi, Abi::Rust, link_name, args)?;
Expand All @@ -69,7 +69,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
}

/// Handles the `try` intrinsic, the underlying implementation of `std::panicking::try`.
fn handle_try(
fn handle_catch_unwind(
&mut self,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
Expand All @@ -85,7 +85,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
// what that is), and returns 1.
// The `payload` is passed (by libstd) to `__rust_panic_cleanup`, which is then expected to
// return a `Box<dyn Any + Send + 'static>`.
// In Miri, `miri_start_panic` is passed exactly that type, so we make the `payload` simply
// In Miri, `miri_start_unwind` is passed exactly that type, so we make the `payload` simply
// a pointer to `Box<dyn Any + Send + 'static>`.

// Get all the arguments.
Expand Down Expand Up @@ -141,7 +141,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
// We set the return value of `try` to 1, since there was a panic.
this.write_scalar(Scalar::from_i32(1), &catch_unwind.dest)?;

// The Thread's `panic_payload` holds what was passed to `miri_start_panic`.
// The Thread's `panic_payload` holds what was passed to `miri_start_unwind`.
// This is exactly the second argument we need to pass to `catch_fn`.
let payload = this.active_thread_mut().panic_payloads.pop().unwrap();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ fn main() {
unsafe {
// Make sure we check the ABI when Miri itself invokes a function
// as part of a shim implementation.
std::intrinsics::r#try(
std::intrinsics::catch_unwind(
//~^ ERROR: calling a function with ABI C using caller ABI Rust
std::mem::transmute::<extern "C" fn(*mut u8), _>(try_fn),
std::ptr::null_mut(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
error: Undefined Behavior: calling a function with ABI C using caller ABI Rust
--> $DIR/check_callback_abi.rs:LL:CC
|
LL | / std::intrinsics::r#try(
LL | / std::intrinsics::catch_unwind(
LL | |
LL | | std::mem::transmute::<extern "C" fn(*mut u8), _>(try_fn),
LL | | std::ptr::null_mut(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
#![feature(c_unwind)]

extern "C" {
fn miri_start_panic(payload: *mut u8) -> !;
fn miri_start_unwind(payload: *mut u8) -> !;
}

fn main() {
unsafe { miri_start_panic(&mut 0) }
unsafe { miri_start_unwind(&mut 0) }
//~^ ERROR: unwinding past a stack frame that does not allow unwinding
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
WARNING: the flag `-Zmiri-disable-abi-check` is deprecated and planned to be removed.
If you have a use-case for it, please file an issue.
error: Undefined Behavior: unwinding past a stack frame that does not allow unwinding
--> $DIR/bad_miri_start_panic.rs:LL:CC
--> $DIR/bad_miri_start_unwind.rs:LL:CC
|
LL | unsafe { miri_start_panic(&mut 0) }
| ^^^^^^^^^^^^^^^^^^^^^^^^ unwinding past a stack frame that does not allow unwinding
LL | unsafe { miri_start_unwind(&mut 0) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^ unwinding past a stack frame that does not allow unwinding
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
= note: BACKTRACE:
= note: inside `main` at $DIR/bad_miri_start_panic.rs:LL:CC
= note: inside `main` at $DIR/bad_miri_start_unwind.rs:LL:CC

note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace

Expand Down
4 changes: 2 additions & 2 deletions src/tools/miri/tests/fail/panic/unwind_panic_abort.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
//! Unwinding despite `-C panic=abort` is an error.

extern "Rust" {
fn miri_start_panic(payload: *mut u8) -> !;
fn miri_start_unwind(payload: *mut u8) -> !;
}

fn main() {
unsafe {
miri_start_panic(&mut 0); //~ ERROR: unwinding past a stack frame that does not allow unwinding
miri_start_unwind(&mut 0); //~ ERROR: unwinding past a stack frame that does not allow unwinding
}
}
4 changes: 2 additions & 2 deletions src/tools/miri/tests/fail/panic/unwind_panic_abort.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error: Undefined Behavior: unwinding past a stack frame that does not allow unwinding
--> $DIR/unwind_panic_abort.rs:LL:CC
|
LL | miri_start_panic(&mut 0);
| ^^^^^^^^^^^^^^^^^^^^^^^^ unwinding past a stack frame that does not allow unwinding
LL | miri_start_unwind(&mut 0);
| ^^^^^^^^^^^^^^^^^^^^^^^^^ unwinding past a stack frame that does not allow unwinding
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ fn main() {
unsafe {
let _ = malloc(0);
std::mem::transmute::<fn(), extern "C" fn()>(foo)();
std::intrinsics::r#try(
std::intrinsics::catch_unwind(
std::mem::transmute::<extern "C" fn(*mut u8), _>(try_fn),
std::ptr::null_mut(),
|_, _| unreachable!(),
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/tests/utils/miri_extern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ extern "Rust" {
///
/// This is internal and unstable and should not be used; we give it here
/// just to be complete.
pub fn miri_start_panic(payload: *mut u8) -> !;
pub fn miri_start_unwind(payload: *mut u8) -> !;

/// Miri-provided extern function to get the internal unique identifier for the allocation that a pointer
/// points to. If this pointer is invalid (not pointing to an allocation), interpretation will abort.
Expand Down
2 changes: 1 addition & 1 deletion tests/assembly/wasm_exceptions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ pub fn test_cleanup() {
#[no_mangle]
pub fn test_rtry() {
unsafe {
core::intrinsics::r#try(|_| {
core::intrinsics::catch_unwind(|_| {
may_panic();
}, core::ptr::null_mut(), |data, exception| {
log_number(data as usize);
Expand Down
2 changes: 1 addition & 1 deletion tests/codegen/wasm_exceptions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ pub fn test_cleanup() {
#[no_mangle]
pub fn test_rtry() {
unsafe {
core::intrinsics::r#try(|_| {
core::intrinsics::catch_unwind(|_| {
may_panic();
}, core::ptr::null_mut(), |data, exception| {
log_number(data as usize);
Expand Down
2 changes: 1 addition & 1 deletion tests/run-make/wasm-exceptions-nostd/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ pub extern "C" fn start() -> usize {
let data = 0x1234usize as *mut u8; // Something to recognize

unsafe {
core::intrinsics::r#try(|data: *mut u8| {
core::intrinsics::catch_unwind(|data: *mut u8| {
let _log_on_drop = LogOnDrop;

logging::log_str(&alloc::format!("`r#try` called with ptr {:?}", data));
Expand Down
Loading
Loading