[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