rust-lang/rust · error
LLVM does not have support for cleanuppad
Error message
LLVM does not have support for cleanuppad
What it means
This panic occurs in rustc's LLVM codegen backend when calling the LLVM-C API `LLVMBuildCleanupPad` to construct a `cleanuppad` instruction (part of Windows/MSVC funclet-based exception handling). The builder.rs code wraps the LLVM call in `Funclet::new(ret.expect(...))`, so if LLVM returns a null/None pointer the compiler panics rather than silently producing broken IR. It exists because funclet EH is required for MSVC targets and a missing LLVM-side implementation is a fatal, unrecoverable configuration mismatch.
Source
Thrown at compiler/rustc_codegen_llvm/src/builder.rs:1316
let mut exn = self.const_poison(ty);
exn = self.insert_value(exn, exn0, 0);
exn = self.insert_value(exn, exn1, 1);
unsafe {
llvm::LLVMBuildResume(self.llbuilder, exn);
}
}
fn cleanup_pad(&mut self, parent: Option<&'ll Value>, args: &[&'ll Value]) -> Funclet<'ll> {
let ret = unsafe {
llvm::LLVMBuildCleanupPad(
self.llbuilder,
parent,
args.as_ptr(),
args.len() as c_uint,
c"cleanuppad".as_ptr(),
)
};
Funclet::new(ret.expect("LLVM does not have support for cleanuppad"))
}
fn cleanup_ret(&mut self, funclet: &Funclet<'ll>, unwind: Option<&'ll BasicBlock>) {
unsafe {
llvm::LLVMBuildCleanupRet(self.llbuilder, funclet.cleanuppad(), unwind)
.expect("LLVM does not have support for cleanupret");
}
}
fn catch_pad(&mut self, parent: &'ll Value, args: &[&'ll Value]) -> Funclet<'ll> {
let ret = unsafe {
llvm::LLVMBuildCatchPad(
self.llbuilder,
parent,
args.as_ptr(),
args.len() as c_uint,
c"catchpad".as_ptr(),
)View on GitHub (pinned to 22057b88b0)
Solutions
- Rebuild/reinstall rustc with the officially bundled LLVM (via `./x.py build`) so funclet EH is compiled in.
- If using a system LLVM, ensure it was configured with `-DLLVM_ENABLE_EH=ON` and the MSVC target backend (`-DLLVM_TARGETS_TO_BUILD` includes X86) and Microsoft extensions enabled.
- Update to a rustc release whose bundled LLVM version is known-good for windows-msvc codegen.
- As a workaround for non-production builds, compile with `-Cpanic=abort` to avoid generating funclet EH IR on that target.
Example fix
// before rustc --target x86_64-pc-windows-msvc --llvm-plugins=/opt/custom-llvm ... // after rustup override set stable # use the toolchain's bundled LLVM rustc --target x86_64-pc-windows-msvc ...
Defensive patterns
Strategy: validation
Validate before calling
# Before building for a Windows SEH target, confirm the active toolchain's
# LLVM was compiled with Windows EH (EHPersonality) support.
rustc --print=target-libdir 2>/dev/null | grep -q . || { echo 'rustc unusable'; exit 1; }
# Reject toolchains known to ship an LLVM stripped of WinEH.
rustc -vV | awk '/release:/ { print }' | grep -Eq 'nightly|stable|beta' \
|| { echo 'custom/custom-LLVM toolchain: WinEH may be missing'; exit 1; }
# Probe the actual target triple; funclet codegen only fires for *-pc-windows-msvc
# / *-pc-windows-gnu with a personality. Bail out early if you don't need it.
case "$RUST_TARGET" in
*windows-msvc*) ;; # supported by stock toolchain
*windows-gnu*) echo 'prefer msvc or verify GNU LLVM has WinEH' ;;
*) ;;
esac Try / catch
# rustc turns this into a panic+non-zero exit; capture it as a subprocess failure.
out="$(cargo build --target "$RUST_TARGET" 2>&1)"; rc=$?
if [ $rc -ne 0 ]; then
case "$out" in
*"LLVM does not have support for cleanuppad"*)
echo "toolchain LLVM lacks WinEH support for $RUST_TARGET" >&2
echo "fix: switch to the stock rustup toolchain or *-windows-msvc" >&2 ;;
*) echo "$out" >&2 ;;
esac
exit $rc
fi Prevention
- Use the rustup-managed stable/beta/nightly toolchain for Windows SEH targets; its bundled LLVM always has WinEH enabled.
- On Windows prefer the MSVC (*-windows-msvc) target over GNU when relying on unwinding/SEH.
- Never pair rustc from one source with an LLVM shared library built with -DLLVM_ENABLE_EH=OFF or with WinEH personalities removed.
- If you build rustc from source, leave the default LLVM feature set intact; do not pass --llvm-skip-rebuild against a hand-patched LLVM.
- Pin toolchains with a rust-toolchain.toml so CI cannot accidentally pick a stripped custom build.
When it happens
Trigger: Compiling code that lowers to cleanuppad landing pads (any Rust `drop`/unwinding destructor during a panic) when targeting an MSVC ABI such as `x86_64-pc-windows-msvc`, while the linked LLVM was built without `MicrosoftExtensions`/EHa or is a downgraded LLVM that lacks the funclet EH intrinsics. The panic fires inside `Builder::cleanup_pad` at builder.rs:1306-1316 once `LLVMBuildCleanupPad` returns null.
Common situations: Building Rust on a Windows MSVC target with a custom/old LLVM; a distro or `--use-libcpp` LLVM build that disabled Windows EH; mismatched `rustc_codegen_llvm` against an in-tree LLVM version that regressed funclet support; cross-compiling to MSVC from a Linux host whose LLVM lacks MSVC EH.
Related errors
- LLVM does not have support for cleanupret
- LLVM does not have support for catchpad
- LLVM does not have support for catchswitch
- LLVM does not have support for catchret
- got a non-UTF8 data-layout from LLVM
AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03).
Data as JSON: /data/errors/4ccd80b10d5c7e59.json.
Report an issue: GitHub.