Skip to content

Commit 99c6342

Browse files
authored
[win] Fix EH Cont Guard targets when SEH personality is used (#129612)
There were two issues when `/guard:ehcont` is enabled with the SEH personality on Windows: 1. As @namazso correctly identified, we bail out of `WinException::endFunction` early for `MSVC_TableSEH` with funclets, expecting the exception data to be emitted in `endFunclet`, but `endFunclet` didn't copy the EHCont metadata from the function to the module. 2. The SEH personality requires that the basic block containing the `catchpad` is the target, not the `catchret`. Fixes #64585
1 parent 718c4ed commit 99c6342

File tree

6 files changed

+19
-4
lines changed

6 files changed

+19
-4
lines changed

llvm/lib/CodeGen/AsmPrinter/WinException.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,12 @@ void WinException::endFuncletImpl() {
290290
// functions that need it in the end anyway.
291291
}
292292

293+
if (!MF->getEHContTargets().empty()) {
294+
// Copy the function's EH Continuation targets to a module-level list.
295+
EHContTargets.insert(EHContTargets.end(), MF->getEHContTargets().begin(),
296+
MF->getEHContTargets().end());
297+
}
298+
293299
// Switch back to the funclet start .text section now that we are done
294300
// writing to .xdata, and emit an .seh_endproc directive to mark the end of
295301
// the function.

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1970,7 +1970,11 @@ void SelectionDAGBuilder::visitCatchPad(const CatchPadInst &I) {
19701970
bool IsCoreCLR = Pers == EHPersonality::CoreCLR;
19711971
bool IsSEH = isAsynchronousEHPersonality(Pers);
19721972
MachineBasicBlock *CatchPadMBB = FuncInfo.MBB;
1973-
if (!IsSEH)
1973+
if (IsSEH) {
1974+
// For SEH, EHCont Guard needs to know that this catchpad is a target.
1975+
CatchPadMBB->setIsEHContTarget(true);
1976+
DAG.getMachineFunction().setHasEHContTarget(true);
1977+
} else
19741978
CatchPadMBB->setIsEHScopeEntry();
19751979
// In MSVC C++ and CoreCLR, catchblocks are funclets and need prologues.
19761980
if (IsMSVCCXX || IsCoreCLR)
@@ -1981,8 +1985,6 @@ void SelectionDAGBuilder::visitCatchRet(const CatchReturnInst &I) {
19811985
// Update machine-CFG edge.
19821986
MachineBasicBlock *TargetMBB = FuncInfo.getMBB(I.getSuccessor());
19831987
FuncInfo.MBB->addSuccessor(TargetMBB);
1984-
TargetMBB->setIsEHContTarget(true);
1985-
DAG.getMachineFunction().setHasEHContTarget(true);
19861988

19871989
auto Pers = classifyEHPersonality(FuncInfo.Fn->getPersonalityFn());
19881990
bool IsSEH = isAsynchronousEHPersonality(Pers);
@@ -1996,6 +1998,10 @@ void SelectionDAGBuilder::visitCatchRet(const CatchReturnInst &I) {
19961998
return;
19971999
}
19982000

2001+
// For non-SEH, EHCont Guard needs to know that this catchret is a target.
2002+
TargetMBB->setIsEHContTarget(true);
2003+
DAG.getMachineFunction().setHasEHContTarget(true);
2004+
19992005
// Figure out the funclet membership for the catchret's successor.
20002006
// This will be used by the FuncletLayout pass to determine how to order the
20012007
// BB's.

llvm/test/CodeGen/AArch64/arm64ec-eh.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ define dso_local i32 @test() #0 personality ptr @__C_specific_handler {
2222
; CHECK-NEXT: bl "#ext"
2323
; CHECK-NEXT: .Ltmp1:
2424
; CHECK-NEXT: .LBB0_1:
25-
; CHECK-NEXT: $ehgcr_0_1:
2625
; CHECK-NEXT: stur w0, [x29, #-4]
2726
; CHECK-NEXT: .seh_startepilogue
2827
; CHECK-NEXT: ldp x29, x30, [sp, #16] // 16-byte Folded Reload
@@ -32,6 +31,7 @@ define dso_local i32 @test() #0 personality ptr @__C_specific_handler {
3231
; CHECK-NEXT: .seh_endepilogue
3332
; CHECK-NEXT: ret
3433
; CHECK-NEXT: .LBB0_2:
34+
; CHECK-NEXT: $ehgcr_0_2:
3535
; CHECK-NEXT: mov w0, wzr
3636
; CHECK-NEXT: b .LBB0_1
3737
%1 = alloca i32, align 4

llvm/test/CodeGen/AArch64/landingpad-ifcvt.ll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
; Make sure this doesn't crash (and the output is sane).
44
; CHECK: // %__except.ret
5+
; CHECK-NEXT: $ehgcr_0_2:
56
; CHECK-NEXT: mov x0, xzr
67

78
target datalayout = "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128"

llvm/test/CodeGen/X86/seh-except-restore.ll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ return: ; preds = %entry, %__except
4848
; CHECK: LBB0_2: # %return
4949

5050
; CHECK: LBB0_1: # %__except.ret
51+
; CHECK-NEXT: $ehgcr_0_1:
5152
; CHECK-NEXT: movl -24(%ebp), %esp
5253
; CHECK-NEXT: addl $12, %ebp
5354

llvm/test/CodeGen/X86/win32-seh-catchpad.ll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ __except:
196196

197197
; CHECK-LABEL: _code_in_catchpad:
198198
; CHECK: # %__except.ret
199+
; CHECK-NEXT: $ehgcr_4_1:
199200
; CHECK-NEXT: movl -24(%ebp), %esp
200201
; CHECK-NEXT: addl $12, %ebp
201202
; CHECK-NEXT: movl $-1, -16(%ebp)

0 commit comments

Comments
 (0)