[llvm] [X86] Don't emit personality info when the personality is not a function (PR #212803)

Zane Hambly via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 29 08:47:37 PDT 2026


https://github.com/Zaneham created https://github.com/llvm/llvm-project/pull/212803

Follow-up to #212417, another one in the same corner.

`llc -mtriple=x86_64-pc-windows-msvc` crashes on a function whose personality isn't a function:

```llvm
define void @a() personality ptr null {
  ret void
}
```

`dyn_cast<Function>` gives null, and `beginFunclet` hands that straight to `getSymbol`, which dereferences it.

`DwarfCFIException` already guards against this, applying the null check to both branches:

```cpp
shouldEmitPersonality =
    (forceEmitPersonality ||
     (hasLandingPads && PerEncoding != dwarf::DW_EH_PE_omit)) && Per;
```

`WinException` has it inside the second operand, so `forceEmitPersonality` bypasses it. Move it out so it gates both, matching the Dwarf path.

The test covers both directions: the null personality no longer emits a handler, and a real personality with a landing pad still emits `.seh_handler __CxxFrameHandler3` as before. `CodeGen/WinEH` is 19/19.

Fixes #210285

>From 9a7756e47e6e7fc65b2567a3adfbb5c8719f0e95 Mon Sep 17 00:00:00 2001
From: Zane Hambly <zanehambly at gmail.com>
Date: Wed, 29 Jul 2026 23:46:00 +1200
Subject: [PATCH] [X86] Don't emit personality info when the personality is not
 a function

---
 llvm/lib/CodeGen/AsmPrinter/WinException.cpp  |  8 +++-
 llvm/test/CodeGen/X86/win-null-personality.ll | 37 +++++++++++++++++++
 2 files changed, 43 insertions(+), 2 deletions(-)
 create mode 100644 llvm/test/CodeGen/X86/win-null-personality.ll

diff --git a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
index e84ad34e1768d..3395e6da6db5a 100644
--- a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
@@ -86,9 +86,13 @@ void WinException::beginFunction(const MachineFunction *MF) {
                               !isNoOpWithoutInvoke(Per) &&
                               F.needsUnwindTableEntry();
 
+  // A personality that is not a function, such as a null pointer, leaves PerFn
+  // empty. Nothing downstream can emit a symbol for it, so gate both cases on
+  // it, the same way DwarfCFIException does.
   shouldEmitPersonality =
-      forceEmitPersonality || ((hasLandingPads || hasEHFunclets) &&
-                               PerEncoding != dwarf::DW_EH_PE_omit && PerFn);
+      (forceEmitPersonality || ((hasLandingPads || hasEHFunclets) &&
+                                PerEncoding != dwarf::DW_EH_PE_omit)) &&
+      PerFn;
 
   unsigned LSDAEncoding = TLOF.getLSDAEncoding();
   shouldEmitLSDA = shouldEmitPersonality &&
diff --git a/llvm/test/CodeGen/X86/win-null-personality.ll b/llvm/test/CodeGen/X86/win-null-personality.ll
new file mode 100644
index 0000000000000..213773ffc0dff
--- /dev/null
+++ b/llvm/test/CodeGen/X86/win-null-personality.ll
@@ -0,0 +1,37 @@
+; RUN: llc -mtriple=x86_64-pc-windows-msvc < %s | FileCheck %s
+
+; A personality that is not a function leaves nothing to emit a symbol for, so
+; no personality or handler data should be produced. This used to crash the
+; X86 assembly printer.
+
+; CHECK-LABEL: null_personality:
+; CHECK-NOT: .seh_handler
+; CHECK: retq
+
+define void @null_personality() personality ptr null {
+  ret void
+}
+
+; A real personality with a landing pad still emits its handler as before.
+
+; CHECK-LABEL: real_personality:
+; CHECK: .seh_handler __CxxFrameHandler3
+
+declare void @g()
+declare i32 @__CxxFrameHandler3(...)
+
+define void @real_personality() personality ptr @__CxxFrameHandler3 {
+entry:
+  invoke void @g()
+          to label %cont unwind label %catch
+
+cont:
+  ret void
+
+catch:
+  %cs = catchswitch within none [label %handler] unwind to caller
+
+handler:
+  %cp = catchpad within %cs [ptr null, i32 64, ptr null]
+  catchret from %cp to label %cont
+}



More information about the llvm-commits mailing list