-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Description
According to https://doc.rust-lang.org/nightly/reference/inline-assembly.html#r-asm.rules.unwind, unwinding out of inline assembly is UB. Indeed, in the LLVM-IR, the nounwind
attribute is applied to any inline assembly.
However, functions that contain inline assembly are currently only marked nounwind
if they have a calling convention that doesn't allow unwinding, such as extern "C"
.
I tried this code:
#[inline(never)]
extern "C" fn asm_noinline() {
unsafe { core::arch::asm!(""); }
}
#[inline(always)]
extern "C" fn asm_inline() {
unsafe { core::arch::asm!(""); }
}
#[unsafe(no_mangle)]
pub fn test_noinline() {
asm_noinline();
}
#[unsafe(no_mangle)]
pub fn test_inline() {
asm_inline();
}
https://godbolt.org/z/z911xcv36
In the LLVM-IR, all functions except test_inline
have the nounwind
attribute. The only reason test_inline
doesn't is that the call to asm_inline
can be inlined, after which there is now inline assembly in the body of an extern "Rust"
function.
Not having nounwind
means that callers of this function will unnecessarily generate landing pads and are also considered potentially unwinding.
Meta
rustc --version --verbose
:
rustc 1.90.0-nightly (b56aaec52 2025-07-24)
binary: rustc
commit-hash: b56aaec52bc0fa35591a872fb4aac81f606e265c
commit-date: 2025-07-24
host: x86_64-unknown-linux-gnu
release: 1.90.0-nightly
LLVM version: 20.1.8
Internal compiler ID: nightly