https://github.com/GkvJwa updated https://github.com/llvm/llvm-project/pull/180144
>From f943bd8f88da850691e834b851e959ead63ab5ef Mon Sep 17 00:00:00 2001 From: GkvJwa <[email protected]> Date: Mon, 23 Mar 2026 23:00:03 +0800 Subject: [PATCH] 1 --- clang/lib/CodeGen/CGCleanup.cpp | 23 ++++++++++++------- clang/lib/CodeGen/CGCleanup.h | 7 ++++++ clang/lib/CodeGen/CGException.cpp | 6 +++-- clang/lib/CodeGen/EHScopeStack.h | 3 +++ .../CodeGen/windows-seh-EHa-TryInFinally.cpp | 11 ++++----- 5 files changed, 34 insertions(+), 16 deletions(-) diff --git a/clang/lib/CodeGen/CGCleanup.cpp b/clang/lib/CodeGen/CGCleanup.cpp index 3d242bec73126..c33f057688b1a 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,7 +194,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()) + !IsSEHFinallyCleanup && CGF->getTarget().getCXXABI().isMicrosoft() && + CGF->getInvokeDest()) CGF->EmitSehCppScopeBegin(); return Scope->getCleanupBuffer(); @@ -785,6 +789,8 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough, // Under -EHa, invoke seh.scope.end() to mark scope end before dtor bool IsEHa = getLangOpts().EHAsynch && !Scope.isLifetimeMarker(); + // Save IsSEHFinallyCleanup before any popCleanup() invalidates Scope. + bool IsSEHFinallyCleanup = Scope.isSEHFinallyCleanup(); const EHPersonality &Personality = EHPersonality::get(*this); if (!RequiresNormalCleanup) { // Mark CPP scope end for passed-by-value Arg temp @@ -811,10 +817,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 +859,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 @@ -1056,7 +1062,8 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough, EHStack.pushTerminate(); PushedTerminate = true; } else if (IsEHa && getInvokeDest()) { - EmitSehCppScopeEnd(); + if (!IsSEHFinallyCleanup) + EmitSehCppScopeEnd(); } // We only actually emit the cleanup code if the cleanup is either 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..eb388740aa0ff 100644 --- a/clang/test/CodeGen/windows-seh-EHa-TryInFinally.cpp +++ b/clang/test/CodeGen/windows-seh-EHa-TryInFinally.cpp @@ -43,11 +43,11 @@ 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 @@ -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: %cleanup.dest2 = 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
