Skip to content

Commit 691927c

Browse files
committed
Fix assertion when try is used inside catch(...) block
Current assert wiht /EHa: A single unwind edge may only enter one EH pad invoke void @llvm.seh.try.begin() to label %invoke.cont1 unwind label %catch.dispatch2 Current IR: %1 = catchpad within %0 [ptr null, i32 0, ptr null] invoke void @llvm.seh.try.begin() to label %invoke.cont5 unwind label %catch.dispatch2 The problem is the invoke to llvm.seh.try.begin() missing "funclet" Accodring: https://llvm.org/docs/LangRef.html#ob-funclet If any "funclet" EH pads have been entered but not exited (per the description in the EH doc), it is undefined behavior to execute a call or invoke. To fix the problem, when emit seh_try_begin, call EmitSehTryScopeBegin, instead of calling EmitRuntimeCallOrInvoke for proper "funclet" gerenration. Differential Revision: https://reviews.llvm.org/D150340
1 parent fcf0a7b commit 691927c

File tree

2 files changed

+28
-1
lines changed

2 files changed

+28
-1
lines changed

clang/lib/CodeGen/CGException.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -646,7 +646,7 @@ void CodeGenFunction::EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) {
646646
// Under async exceptions, catch(...) need to catch HW exception too
647647
// Mark scope with SehTryBegin as a SEH __try scope
648648
if (getLangOpts().EHAsynch)
649-
EmitRuntimeCallOrInvoke(getSehTryBeginFn(CGM));
649+
EmitSehTryScopeBegin();
650650
}
651651
}
652652
}

clang/test/CodeGen/windows-seh-EHa-CppCatchDotDotDot.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,21 @@
99
// CHECK: %[[dst1:[0-9-]+]] = catchpad within %[[dst]] [ptr null, i32 0, ptr null]
1010
// CHECK: "funclet"(token %[[dst1]])
1111

12+
// CHECK: define dso_local void @"?bar@@YAXXZ
13+
// CHECK: invoke void @llvm.seh.try.begin()
14+
// CHECK: invoke void @_CxxThrowException
15+
// CHECK: %[[dst:[0-9-]+]] = catchpad within %0 [ptr null, i32 0, ptr null]
16+
// CHECK: invoke void @llvm.seh.try.begin() [ "funclet"(token %[[dst]]) ]
17+
1218
// CHECK: invoke void @llvm.seh.try.begin()
1319
// CHECK: %[[src:[0-9-]+]] = load volatile i32, ptr %i
1420
// CHECK-NEXT: invoke void @"?crash@@YAXH@Z"(i32 noundef %[[src]])
1521
// CHECK: invoke void @llvm.seh.try.end()
1622

23+
// CHECK: invoke void @llvm.seh.try.begin()
24+
// CHECK: invoke void @"?bar@@YAXXZ"()
25+
// CHECK: invoke void @llvm.seh.try.end()
26+
1727
// *****************************************************************************
1828
// Abstract: Test CPP catch(...) under SEH -EHa option
1929

@@ -46,6 +56,18 @@ void crash(int i) {
4656
}
4757
}
4858

59+
void bar() {
60+
try {
61+
throw 1;
62+
} catch(...) {
63+
try {
64+
*NullPtr = 0;
65+
} catch (...) {
66+
throw 1;
67+
}
68+
}
69+
}
70+
4971
int main() {
5072
for (int i = 0; i < 2; i++) {
5173
__try {
@@ -54,5 +76,10 @@ int main() {
5476
printf(" Test CPP unwind: in except handler i = %d \n", i);
5577
}
5678
}
79+
__try {
80+
bar();
81+
} __except (1) {
82+
printf("Test CPP unwind: in except handler \n");
83+
}
5784
return 0;
5885
}

0 commit comments

Comments
 (0)