[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