{"id":"4ccd80b10d5c7e59","repo":"rust-lang/rust","slug":"llvm-does-not-have-support-for-cleanuppad","errorCode":null,"errorMessage":"LLVM does not have support for cleanuppad","messagePattern":"LLVM does not have support for cleanuppad","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compiler/rustc_codegen_llvm/src/builder.rs","lineNumber":1316,"sourceCode":"        let mut exn = self.const_poison(ty);\n        exn = self.insert_value(exn, exn0, 0);\n        exn = self.insert_value(exn, exn1, 1);\n        unsafe {\n            llvm::LLVMBuildResume(self.llbuilder, exn);\n        }\n    }\n\n    fn cleanup_pad(&mut self, parent: Option<&'ll Value>, args: &[&'ll Value]) -> Funclet<'ll> {\n        let ret = unsafe {\n            llvm::LLVMBuildCleanupPad(\n                self.llbuilder,\n                parent,\n                args.as_ptr(),\n                args.len() as c_uint,\n                c\"cleanuppad\".as_ptr(),\n            )\n        };\n        Funclet::new(ret.expect(\"LLVM does not have support for cleanuppad\"))\n    }\n\n    fn cleanup_ret(&mut self, funclet: &Funclet<'ll>, unwind: Option<&'ll BasicBlock>) {\n        unsafe {\n            llvm::LLVMBuildCleanupRet(self.llbuilder, funclet.cleanuppad(), unwind)\n                .expect(\"LLVM does not have support for cleanupret\");\n        }\n    }\n\n    fn catch_pad(&mut self, parent: &'ll Value, args: &[&'ll Value]) -> Funclet<'ll> {\n        let ret = unsafe {\n            llvm::LLVMBuildCatchPad(\n                self.llbuilder,\n                parent,\n                args.as_ptr(),\n                args.len() as c_uint,\n                c\"catchpad\".as_ptr(),\n            )","sourceCodeStart":1298,"sourceCodeEnd":1334,"githubUrl":"https://github.com/rust-lang/rust/blob/22057b88b091743bc0fd8d592a9264f0a6951403/compiler/rustc_codegen_llvm/src/builder.rs#L1298-L1334","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nrustc --target x86_64-pc-windows-msvc --llvm-plugins=/opt/custom-llvm ...\n// after\nrustup override set stable   # use the toolchain's bundled LLVM\nrustc --target x86_64-pc-windows-msvc ...","handlingStrategy":"validation","validationCode":"# Before building for a Windows SEH target, confirm the active toolchain's\n# LLVM was compiled with Windows EH (EHPersonality) support.\nrustc --print=target-libdir 2>/dev/null | grep -q . || { echo 'rustc unusable'; exit 1; }\n# Reject toolchains known to ship an LLVM stripped of WinEH.\nrustc -vV | awk '/release:/ { print }' | grep -Eq 'nightly|stable|beta' \\\n  || { echo 'custom/custom-LLVM toolchain: WinEH may be missing'; exit 1; }\n# Probe the actual target triple; funclet codegen only fires for *-pc-windows-msvc\n# / *-pc-windows-gnu with a personality. Bail out early if you don't need it.\ncase \"$RUST_TARGET\" in\n  *windows-msvc*) ;;            # supported by stock toolchain\n  *windows-gnu*) echo 'prefer msvc or verify GNU LLVM has WinEH' ;;\n  *) ;;\nesac","typeGuard":null,"tryCatchPattern":"# rustc turns this into a panic+non-zero exit; capture it as a subprocess failure.\nout=\"$(cargo build --target \"$RUST_TARGET\" 2>&1)\"; rc=$?\nif [ $rc -ne 0 ]; then\n  case \"$out\" in\n    *\"LLVM does not have support for cleanuppad\"*)\n      echo \"toolchain LLVM lacks WinEH support for $RUST_TARGET\" >&2\n      echo \"fix: switch to the stock rustup toolchain or *-windows-msvc\" >&2 ;;\n    *) echo \"$out\" >&2 ;;\n  esac\n  exit $rc\nfi","preventionTips":["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."],"tags":["llvm","code-generation","windows","exception-handling","panic"],"analyzedSha":"22057b88b091743bc0fd8d592a9264f0a6951403","analyzedAt":"2026-08-03T08:09:25.915Z","schemaVersion":2}