{"id":"c587526409015e72","repo":"rust-lang/rust","slug":"llvm-does-not-have-support-for-catchret","errorCode":null,"errorMessage":"LLVM does not have support for catchret","messagePattern":"LLVM does not have support for catchret","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compiler/rustc_codegen_llvm/src/builder.rs","lineNumber":1813,"sourceCode":"            &[self.val_ty(src)],\n            &[src],\n        )\n    }\n}\nimpl<'a, 'll, CX: Borrow<SCx<'ll>>> GenericBuilder<'a, 'll, CX> {\n    pub(crate) fn add_clause(&mut self, landing_pad: &'ll Value, clause: &'ll Value) {\n        unsafe {\n            llvm::LLVMAddClause(landing_pad, clause);\n        }\n    }\n\n    pub(crate) fn catch_ret(\n        &mut self,\n        funclet: &Funclet<'ll>,\n        unwind: &'ll BasicBlock,\n    ) -> &'ll Value {\n        let ret = unsafe { llvm::LLVMBuildCatchRet(self.llbuilder, funclet.cleanuppad(), unwind) };\n        ret.expect(\"LLVM does not have support for catchret\")\n    }\n\n    pub(crate) fn check_call<'b>(\n        &mut self,\n        typ: &str,\n        fn_ty: &'ll Type,\n        llfn: &'ll Value,\n        args: &'b [&'ll Value],\n    ) -> Cow<'b, [&'ll Value]> {\n        assert!(\n            self.cx.type_kind(fn_ty) == TypeKind::Function,\n            \"builder::{typ} not passed a function, but {fn_ty:?}\"\n        );\n\n        let param_tys = self.cx.func_params_types(fn_ty);\n\n        let all_args_match = iter::zip(&param_tys, args.iter().map(|&v| self.cx.val_ty(v)))\n            .all(|(expected_ty, actual_ty)| *expected_ty == actual_ty);","sourceCodeStart":1795,"sourceCodeEnd":1831,"githubUrl":"https://github.com/rust-lang/rust/blob/22057b88b091743bc0fd8d592a9264f0a6951403/compiler/rustc_codegen_llvm/src/builder.rs#L1795-L1831","documentation":"This panic is raised by `GenericBuilder::catch_ret` (builder.rs:1807-1813) when the LLVM-C call `LLVMBuildCatchRet` returns None. catchret exits a SEH catch funclet and transfers control back to normal code on MSVC targets; a null return means the linked LLVM cannot produce it. The `.expect(\"LLVM does not have support for catchret\")` guard converts the unsupported instruction into an immediate compiler panic because partial funclet IR is invalid.","triggerScenarios":"Compiling any SEH catch block whose exit must be lowered to a `catchret` when targeting `*-pc-windows-msvc`, while LLVM returns null from `LLVMBuildCatchRet`. Triggers at builder.rs:1812-1813 inside the codegen of the catch handler's terminator.","commonSituations":"Custom/system LLVM lacking MSVC EH; rustc-vs-LLVM version skew; cross-compiling to MSVC with a host LLVM that does not implement catchret.","solutions":["Use the rustc toolchain's bundled LLVM.","Rebuild LLVM with EH (`-DLLVM_ENABLE_EH=ON`) and the X86 MSVC target.","Align rustc and LLVM versions (rebuild from source).","Avoid the MSVC target or compile with `-Cpanic=abort` to skip catchret emission."],"exampleFix":"// before\nrustc --target x86_64-pc-windows-msvc -Cpanic=unwind\n// after\nrustc --target x86_64-pc-windows-msvc -Cpanic=abort   # no catchret needed","handlingStrategy":"validation","validationCode":"# catchret returns from a catch handler; emitted alongside catchswitch.\n# Validate that panic=unwind is even meaningful for this LLVM before relying on it.\nrustc -C panic=unwind --print=cfg 2>/dev/null | grep -q panic=unwind \\\n  || echo 'NOTE: unwind cfg not honoured; SEH catchret may be unlowerable on this LLVM'","typeGuard":null,"tryCatchPattern":"out=\"$(cargo build 2>&1)\"; rc=$?\nif [ $rc -ne 0 ]; then\n  case \"$out\" in\n    *\"LLVM does not have support for catchret\"*)\n      echo \"catchret unlowerable; use a WinEH-capable LLVM or avoid catching across FFI\" >&2 ;;\n    *) echo \"$out\" >&2 ;;\n  esac\n  exit $rc\nfi","preventionTips":["Keep SEH-catching code on the MSVC target and the rustup default LLVM.","Don't ship custom libLLVM.so alongside rustc unless EH is enabled at LLVM build time.","Lock the toolchain in CI with rust-toolchain.toml.","If you only need unwinding (not catching), prefer -Cpanic=unwind on a verified toolchain over SEH catch constructs."],"tags":["llvm","code-generation","windows","exception-handling","panic"],"analyzedSha":"22057b88b091743bc0fd8d592a9264f0a6951403","analyzedAt":"2026-08-03T08:09:25.915Z","schemaVersion":2}