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
