[clang] [clang][seh]: Fix c++ destructors when c++ exceptions are disabled (PR #151836)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Aug 2 12:44:03 PDT 2025
https://github.com/Qwinci created https://github.com/llvm/llvm-project/pull/151836
Don't generate calls to llvm.seh.scope.{begin,end} if c++ exceptions are disabled. Currently clang sometimes causes LLVM to crash due to invalid usage of the seh intrinsics when c++ objects with destructors are in scope with __try/__except when using -fasync-exceptions (see https://github.com/llvm/llvm-project/issues/82917). I am not sure why the assert that I removed fails with the changes, it would be nice if someone who knows more about the seh code would comment on this. CC @phoebewang
>From 1397a144eaa5e20fbf0478c397a74f7deb7dbe46 Mon Sep 17 00:00:00 2001
From: Qwinci <qwinci222 at gmail.com>
Date: Sat, 2 Aug 2025 22:20:41 +0300
Subject: [PATCH] [clang][seh]: Fix c++ destructors when c++ exceptions are
disabled
Don't generate calls to llvm.seh.scope.{begin,end} if c++ exceptions are
disabled. Currently clang sometimes causes LLVM to crash due to invalid usage
of the seh intrinsics when c++ objects with destructors are in scope with
__try/__except.
---
clang/lib/CodeGen/CGCleanup.cpp | 8 ++++----
clang/lib/CodeGen/CGStmt.cpp | 2 +-
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/clang/lib/CodeGen/CGCleanup.cpp b/clang/lib/CodeGen/CGCleanup.cpp
index 7e1c5b7da9552..b429ccb993ce7 100644
--- a/clang/lib/CodeGen/CGCleanup.cpp
+++ b/clang/lib/CodeGen/CGCleanup.cpp
@@ -191,7 +191,8 @@ void *EHScopeStack::pushCleanup(CleanupKind Kind, size_t Size) {
// consistent with MSVC's behavior, except in the presence of -EHa.
// Check getInvokeDest() to generate llvm.seh.scope.begin() as needed.
if (CGF->getLangOpts().EHAsynch && IsEHCleanup && !IsLifetimeMarker &&
- CGF->getTarget().getCXXABI().isMicrosoft() && CGF->getInvokeDest())
+ CGF->getTarget().getCXXABI().isMicrosoft() && CGF->getInvokeDest() &&
+ CGF->getLangOpts().CXXExceptions)
CGF->EmitSehCppScopeBegin();
return Scope->getCleanupBuffer();
@@ -674,7 +675,6 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough,
// Check whether we need an EH cleanup. This is only true if we've
// generated a lazy EH cleanup block.
llvm::BasicBlock *EHEntry = Scope.getCachedEHDispatchBlock();
- assert(Scope.hasEHBranches() == (EHEntry != nullptr));
bool RequiresEHCleanup = (EHEntry != nullptr);
EHScopeStack::stable_iterator EHParent = Scope.getEnclosingEHScope();
@@ -810,7 +810,7 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough,
!HasExistingBranches) {
// mark SEH scope end for fall-through flow
- if (IsEHa && getInvokeDest()) {
+ if (IsEHa && getInvokeDest() && getLangOpts().CXXExceptions) {
if (Personality.isMSVCXXPersonality())
EmitSehCppScopeEnd();
else
@@ -852,7 +852,7 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough,
EmitBlock(NormalEntry);
// intercept normal cleanup to mark SEH scope end
- if (IsEHa && getInvokeDest()) {
+ if (IsEHa && getInvokeDest() && getLangOpts().CXXExceptions) {
if (Personality.isMSVCXXPersonality())
EmitSehCppScopeEnd();
else
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index 7368df1ebe272..80e1aac452cc0 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -772,7 +772,7 @@ void CodeGenFunction::EmitLabelStmt(const LabelStmt &S) {
EmitLabel(S.getDecl());
// IsEHa - emit eha.scope.begin if it's a side entry of a scope
- if (getLangOpts().EHAsynch && S.isSideEntry())
+ if (getLangOpts().EHAsynch && getLangOpts().CXXExceptions && S.isSideEntry())
EmitSehCppScopeBegin();
EmitStmt(S.getSubStmt());
More information about the cfe-commits
mailing list