[clang] [CIR] Propagate correct flags to EHCleanupScope (PR #179137)

via cfe-commits cfe-commits at lists.llvm.org
Sun Feb 1 13:07:07 PST 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clangir

Author: Amr Hesham (AmrDeveloper)

<details>
<summary>Changes</summary>

Propagate correct flags to the EHCleanupScope, which will be needed to trigger the invoke branch inside `emitCallLikeOp`. This code will make ClangIR trigger NYI for cleanups that need to be called inside the cleanup scope, but now they are produced in the main function scope, which is wrong

---
Full diff: https://github.com/llvm/llvm-project/pull/179137.diff


2 Files Affected:

- (modified) clang/lib/CIR/CodeGen/CIRGenCleanup.cpp (+14-2) 
- (modified) clang/lib/CIR/CodeGen/CIRGenCleanup.h (+4-5) 


``````````diff
diff --git a/clang/lib/CIR/CodeGen/CIRGenCleanup.cpp b/clang/lib/CIR/CodeGen/CIRGenCleanup.cpp
index 8d9ea7c6c22eb..01fd9e1004bc3 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCleanup.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCleanup.cpp
@@ -147,12 +147,24 @@ void *EHScopeStack::pushCleanup(CleanupKind kind, size_t size) {
 
   assert(!cir::MissingFeatures::innermostEHScope());
 
-  EHCleanupScope *scope = new (buffer) EHCleanupScope(
-      size, branchFixups.size(), innermostNormalCleanup, innermostEHScope);
+  // Per C++ [except.terminate], it is implementation-defined whether none,
+  // some, or all cleanups are called before std::terminate. Thus, when
+  // terminate is the current EH scope, we may skip adding any EH cleanup
+  // scopes.
+  if (innermostEHScope != stable_end() &&
+      find(innermostEHScope)->getKind() == EHScope::Terminate)
+    isEHCleanup = false;
+
+  EHCleanupScope *scope = new (buffer)
+      EHCleanupScope(isNormalCleanup, isEHCleanup, size, branchFixups.size(),
+                     innermostNormalCleanup, innermostEHScope);
 
   if (isNormalCleanup)
     innermostNormalCleanup = stable_begin();
 
+  if (isEHCleanup)
+    innermostEHScope = stable_begin();
+
   if (isLifetimeMarker)
     cgf->cgm.errorNYI("push lifetime marker cleanup");
 
diff --git a/clang/lib/CIR/CodeGen/CIRGenCleanup.h b/clang/lib/CIR/CodeGen/CIRGenCleanup.h
index 85dbde4058889..6ad90a9072968 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCleanup.h
+++ b/clang/lib/CIR/CodeGen/CIRGenCleanup.h
@@ -211,15 +211,14 @@ class alignas(EHScopeStack::ScopeStackAlignment) EHCleanupScope
     return sizeof(EHCleanupScope) + cleanupBits.cleanupSize;
   }
 
-  EHCleanupScope(unsigned cleanupSize, unsigned fixupDepth,
+  EHCleanupScope(bool isNormal, bool isEH, unsigned cleanupSize,
+                 unsigned fixupDepth,
                  EHScopeStack::stable_iterator enclosingNormal,
                  EHScopeStack::stable_iterator enclosingEH)
       : EHScope(EHScope::Cleanup, enclosingEH),
         enclosingNormal(enclosingNormal), fixupDepth(fixupDepth) {
-    // TODO(cir): When exception handling is upstreamed, isNormalCleanup and
-    // isEHCleanup will be arguments to the constructor.
-    cleanupBits.isNormalCleanup = true;
-    cleanupBits.isEHCleanup = false;
+    cleanupBits.isNormalCleanup = isNormal;
+    cleanupBits.isEHCleanup = isEH;
     cleanupBits.isActive = true;
     cleanupBits.isLifetimeMarker = false;
     cleanupBits.testFlagInNormalCleanup = false;

``````````

</details>


https://github.com/llvm/llvm-project/pull/179137


More information about the cfe-commits mailing list