https://github.com/GkvJwa updated 
https://github.com/llvm/llvm-project/pull/180144

>From 66652112b26212e0e11e58b4e934f3762a458da1 Mon Sep 17 00:00:00 2001
From: GkvJwa <[email protected]>
Date: Mon, 23 Mar 2026 22:11:32 +0800
Subject: [PATCH] 1

---
 clang/lib/CodeGen/CGCleanup.cpp               | 16 ++++++++++------
 clang/lib/CodeGen/CGCleanup.h                 |  7 +++++++
 clang/lib/CodeGen/CGException.cpp             |  6 ++++--
 clang/lib/CodeGen/EHScopeStack.h              |  3 +++
 .../CodeGen/windows-seh-EHa-TryInFinally.cpp  | 19 +++++++++----------
 5 files changed, 33 insertions(+), 18 deletions(-)

diff --git a/clang/lib/CodeGen/CGCleanup.cpp b/clang/lib/CodeGen/CGCleanup.cpp
index 3d242bec73126..c3ae1f0c81b03 100644
--- a/clang/lib/CodeGen/CGCleanup.cpp
+++ b/clang/lib/CodeGen/CGCleanup.cpp
@@ -159,6 +159,7 @@ void *EHScopeStack::pushCleanup(CleanupKind Kind, size_t 
Size) {
   bool IsEHCleanup = Kind & EHCleanup;
   bool IsLifetimeMarker = Kind & LifetimeMarker;
   bool IsFakeUse = Kind & FakeUse;
+  bool IsSEHFinallyCleanup = Kind & SEHFinallyCleanup;
 
   // Per C++ [except.terminate], it is implementation-defined whether none,
   // some, or all cleanups are called before std::terminate. Thus, when
@@ -183,6 +184,8 @@ void *EHScopeStack::pushCleanup(CleanupKind Kind, size_t 
Size) {
     Scope->setLifetimeMarker();
   if (IsFakeUse)
     Scope->setFakeUse();
+  if (IsSEHFinallyCleanup)
+    Scope->setSEHFinallyCleanup();
 
   // With Windows -EHa, Invoke llvm.seh.scope.begin() for EHCleanup
   // If exceptions are disabled/ignored and SEH is not in use, then there is no
@@ -191,6 +194,7 @@ 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 &&
+      !IsSEHFinallyCleanup &&
       CGF->getTarget().getCXXABI().isMicrosoft() && CGF->getInvokeDest())
     CGF->EmitSehCppScopeBegin();
 
@@ -811,10 +815,10 @@ void CodeGenFunction::PopCleanupBlock(bool 
FallthroughIsBranchThrough,
 
       // mark SEH scope end for fall-through flow
       if (IsEHa && getInvokeDest()) {
-        if (Personality.isMSVCXXPersonality())
-          EmitSehCppScopeEnd();
-        else
+        if (Scope.isSEHFinallyCleanup())
           EmitSehTryScopeEnd();
+        else if (Personality.isMSVCPersonality())
+          EmitSehCppScopeEnd();
       }
 
       destroyOptimisticNormalEntry(*this, Scope);
@@ -853,10 +857,10 @@ void CodeGenFunction::PopCleanupBlock(bool 
FallthroughIsBranchThrough,
 
       // intercept normal cleanup to mark SEH scope end
       if (IsEHa && getInvokeDest()) {
-        if (Personality.isMSVCXXPersonality())
-          EmitSehCppScopeEnd();
-        else
+        if (Scope.isSEHFinallyCleanup())
           EmitSehTryScopeEnd();
+        else if (Personality.isMSVCPersonality())
+          EmitSehCppScopeEnd();
       }
 
       // III.  Figure out where we're going and build the cleanup
diff --git a/clang/lib/CodeGen/CGCleanup.h b/clang/lib/CodeGen/CGCleanup.h
index ba78e5478ac37..ded8be13c5fae 100644
--- a/clang/lib/CodeGen/CGCleanup.h
+++ b/clang/lib/CodeGen/CGCleanup.h
@@ -99,6 +99,9 @@ class EHScope {
     LLVM_PREFERRED_TYPE(bool)
     unsigned TestFlagInEHCleanup : 1;
 
+    LLVM_PREFERRED_TYPE(bool)
+    unsigned IsSEHFinallyCleanup : 1;
+
     /// The amount of extra storage needed by the Cleanup.
     /// Always a multiple of the scope-stack alignment.
     unsigned CleanupSize : 12;
@@ -357,6 +360,7 @@ class alignas(8) EHCleanupScope : public EHScope {
     CleanupBits.IsActive = true;
     CleanupBits.IsLifetimeMarker = false;
     CleanupBits.IsFakeUse = false;
+    CleanupBits.IsSEHFinallyCleanup = false;
     CleanupBits.TestFlagInNormalCleanup = false;
     CleanupBits.TestFlagInEHCleanup = false;
     CleanupBits.CleanupSize = cleanupSize;
@@ -392,6 +396,9 @@ class alignas(8) EHCleanupScope : public EHScope {
   bool isFakeUse() const { return CleanupBits.IsFakeUse; }
   void setFakeUse() { CleanupBits.IsFakeUse = true; }
 
+  bool isSEHFinallyCleanup() const { return CleanupBits.IsSEHFinallyCleanup; }
+  void setSEHFinallyCleanup() { CleanupBits.IsSEHFinallyCleanup = true; }
+
   bool hasActiveFlag() const { return ActiveFlag.isValid(); }
   Address getActiveFlag() const {
     return ActiveFlag;
diff --git a/clang/lib/CodeGen/CGException.cpp 
b/clang/lib/CodeGen/CGException.cpp
index 7559727721496..fcbb473228c01 100644
--- a/clang/lib/CodeGen/CGException.cpp
+++ b/clang/lib/CodeGen/CGException.cpp
@@ -2182,7 +2182,8 @@ llvm::Value 
*CodeGenFunction::EmitSEHAbnormalTermination() {
 
 void CodeGenFunction::pushSEHCleanup(CleanupKind Kind,
                                      llvm::Function *FinallyFunc) {
-  EHStack.pushCleanup<PerformSEHFinally>(Kind, FinallyFunc);
+  EHStack.pushCleanup<PerformSEHFinally>(
+      static_cast<CleanupKind>(Kind | SEHFinallyCleanup), FinallyFunc);
 }
 
 void CodeGenFunction::EnterSEHTryStmt(const SEHTryStmt &S) {
@@ -2194,7 +2195,8 @@ void CodeGenFunction::EnterSEHTryStmt(const SEHTryStmt 
&S) {
         HelperCGF.GenerateSEHFinallyFunction(*this, *Finally);
 
     // Push a cleanup for __finally blocks.
-    EHStack.pushCleanup<PerformSEHFinally>(NormalAndEHCleanup, FinallyFunc);
+    EHStack.pushCleanup<PerformSEHFinally>(NormalAndEHSEHFinallyCleanup,
+                                           FinallyFunc);
     return;
   }
 
diff --git a/clang/lib/CodeGen/EHScopeStack.h b/clang/lib/CodeGen/EHScopeStack.h
index b9b8021191d62..2f5e056e7db3b 100644
--- a/clang/lib/CodeGen/EHScopeStack.h
+++ b/clang/lib/CodeGen/EHScopeStack.h
@@ -92,6 +92,9 @@ enum CleanupKind : unsigned {
   // markers chiefly to be ignored in most contexts.
   FakeUse = 0x10,
   NormalFakeUse = FakeUse | NormalCleanup,
+
+  SEHFinallyCleanup = 0x20,
+  NormalAndEHSEHFinallyCleanup = SEHFinallyCleanup | NormalAndEHCleanup,
 };
 
 /// A stack of scopes which respond to exceptions, including cleanups
diff --git a/clang/test/CodeGen/windows-seh-EHa-TryInFinally.cpp 
b/clang/test/CodeGen/windows-seh-EHa-TryInFinally.cpp
index 462ba9afb5b30..251ed8191aab9 100644
--- a/clang/test/CodeGen/windows-seh-EHa-TryInFinally.cpp
+++ b/clang/test/CodeGen/windows-seh-EHa-TryInFinally.cpp
@@ -43,17 +43,17 @@ int main() {
 }
 
 // CHECK-LABEL:@"?foo@@YAXXZ"()
-// CHECK: invoke.cont:
 // CHECK: invoke void @llvm.seh.try.begin()
+// CHECK: invoke.cont:
 // CHECK: store volatile i32 1, ptr %cleanup.dest.slot
 // CHECK: invoke void @llvm.seh.try.end()
-// CHECK: invoke.cont2:
+// CHECK: invoke.cont1:
 // CHECK: %cleanup.dest = load i32, ptr %cleanup.dest.slot
-// CHECK: %1 = icmp ne i32 %cleanup.dest, 0
-// CHECK: %2 = zext i1 %1 to i8
-// CHECK: call void @"?fin$0@0@foo@@"(i8 noundef %2, ptr noundef %0)
+// CHECK: icmp ne i32 %cleanup.dest, 0
+// CHECK: zext i1
+// CHECK: call void @"?fin$0@0@foo@@"(i8 noundef
 // CHECK: ehcleanup:
-// CHECK: call void @"?fin$0@0@foo@@"(i8 noundef 1, ptr noundef %4)
+// CHECK: call void @"?fin$0@0@foo@@"(i8 noundef 1,
 void foo()
 {
   __try {
@@ -69,14 +69,13 @@ void foo()
 }
 
 // CHECK-LABEL:@"?bar@@YAHXZ"()
-// CHECK: invoke.cont:
 // CHECK: invoke void @llvm.seh.try.begin()
-// CHECK: invoke.cont1:
+// CHECK: invoke.cont:
 // CHECK: store volatile i32 1, ptr %cleanup.dest.slot
 // CHECK: invoke void @llvm.seh.try.end()
-// CHECK: invoke.cont2:
+// CHECK: invoke.cont1:
 // CHECK: call void @"?fin$0@0@bar@@"
-// CHECK: %cleanup.dest3 = load i32, ptr %cleanup.dest.slot
+// CHECK: load i32, ptr %cleanup.dest.slot
 // CHECK: return:
 // CHECK: ret i32 11
 int bar()

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to