rust-lang/rust · error

LLVM does not have support for catchswitch

Error message

LLVM does not have support for catchswitch

What it means

This panic is raised by `Builder::catch_switch` (builder.rs:1339-1354) when the LLVM-C API `LLVMBuildCatchSwitch` returns null. The catchswitch instruction is the root of a Windows SEH catch handler within a funclet; if LLVM cannot build one, codegen cannot proceed and `.expect("LLVM does not have support for catchswitch")` aborts the compiler. Like the other funclet EH panics it signals that the linked LLVM lacks MSVC exception-handling support.

Source

Thrown at compiler/rustc_codegen_llvm/src/builder.rs:1354

        Funclet::new(ret.expect("LLVM does not have support for catchpad"))
    }

    fn catch_switch(
        &mut self,
        parent: Option<&'ll Value>,
        unwind: Option<&'ll BasicBlock>,
        handlers: &[&'ll BasicBlock],
    ) -> &'ll Value {
        let ret = unsafe {
            llvm::LLVMBuildCatchSwitch(
                self.llbuilder,
                parent,
                unwind,
                handlers.len() as c_uint,
                c"catchswitch".as_ptr(),
            )
        };
        let ret = ret.expect("LLVM does not have support for catchswitch");
        for handler in handlers {
            unsafe {
                llvm::LLVMAddHandler(ret, handler);
            }
        }
        ret
    }

    fn get_funclet_cleanuppad(&self, funclet: &Funclet<'ll>) -> &'ll Value {
        funclet.cleanuppad()
    }

    // Atomic Operations
    fn atomic_cmpxchg(
        &mut self,
        dst: &'ll Value,
        cmp: &'ll Value,
        src: &'ll Value,

View on GitHub (pinned to 22057b88b0)

Solutions

  1. Use rustc's bundled LLVM (default toolchain).
  2. Rebuild LLVM with exception handling and the MSVC-capable X86 backend.
  3. Match rustc and LLVM versions exactly (rebuild rustc via `./x.py build`).
  4. Switch panic strategy (`-Cpanic=abort`) or use a non-MSVC target to sidestep catchswitch emission.

Example fix

// before
RUSTFLAGS="-Clinker=lld-link" rustc --target x86_64-pc-windows-msvc app.rs
// after
rustc +stable --target x86_64-pc-windows-msvc app.rs
Defensive patterns

Strategy: validation

Validate before calling

# catchswitch is the root of an SEH catch dispatch. Same trigger class as
# 170-172; reuse the toolchain-integrity probe.
rustc --version --verbose | grep -E '^release:' >/dev/null || { echo 'unidentified toolchain'; exit 1; }
rustc --print=sysroot >/dev/null 2>&1 || { echo 'broken sysroot'; exit 1; }

Try / catch

out="$(cargo build 2>&1)"; rc=$?
if [ $rc -ne 0 ]; then
  case "$out" in
    *"LLVM does not have support for catchswitch"*)
      echo "SEH catchswitch unsupported by this LLVM; switch toolchain or target" >&2 ;;
    *) echo "$out" >&2 ;;
  esac
  exit $rc
fi

Prevention

When it happens

Trigger: Compiling unwinding code that needs a catch handler dispatch on an MSVC target (`x86_64-pc-windows-msvc`/`i686-pc-windows-msvc`) and LLVM's `LLVMBuildCatchSwitch` returns None. The panic happens at builder.rs:1354 right after the FFI call, before any handlers can be added via `LLVMAddHandler`.

Common situations: Toolchain with a system/custom LLVM missing EH; rustc built without the matching LLVM commit; cross-compile to MSVC from a host LLVM that lacks MSVC EH support.

Related errors


AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03). Data as JSON: /data/errors/38559ec5f830f407.json. Report an issue: GitHub.