Function rustc_middle::ty::layout::fn_can_unwind
source · Expand description
Calculates whether a function’s ABI can unwind or not.
This takes two primary parameters:
-
codegen_fn_attr_flags
- these are flags calculated as part of the codegen attrs for a defined function. For function pointers this set of flags is the empty set. This is only applicable for Rust-defined functions, and generally isn’t needed except for small optimizations where we try to say a function which otherwise might look like it could unwind doesn’t actually unwind (such as for intrinsics and such). -
abi
- this is the ABI that the function is defined with. This is the primary factor for determining whether a function can unwind or not.
Note that in this case unwinding is not necessarily panicking in Rust. Rust
panics are implemented with unwinds on most platform (when
-Cpanic=unwind
), but this also accounts for -Cpanic=abort
build modes.
Notably unwinding is disallowed for more non-Rust ABIs unless it’s
specifically in the name (e.g. "C-unwind"
). Unwinding within each ABI is
defined for each ABI individually, but it always corresponds to some form of
stack-based unwinding (the exact mechanism of which varies
platform-by-platform).
Rust functions are classified whether or not they can unwind based on the
active “panic strategy”. In other words Rust functions are considered to
unwind in -Cpanic=unwind
mode and cannot unwind in -Cpanic=abort
mode.
Note that Rust supports intermingling panic=abort and panic=unwind code, but
only if the final panic mode is panic=abort. In this scenario any code
previously compiled assuming that a function can unwind is still correct, it
just never happens to actually unwind at runtime.
This function’s answer to whether or not a function can unwind is quite impactful throughout the compiler. This affects things like:
- Calling a function which can’t unwind means codegen simply ignores any associated unwinding cleanup.
- Calling a function which can unwind from a function which can’t unwind
causes the
abort_unwinding_calls
MIR pass to insert a landing pad that aborts the process. - This affects whether functions have the LLVM
nounwind
attribute, which affects various optimizations and codegen.
FIXME: this is actually buggy with respect to Rust functions. Rust functions
compiled with -Cpanic=unwind
and referenced from another crate compiled
with -Cpanic=abort
will look like they can’t unwind when in fact they
might (from a foreign exception or similar).