[clang] [CIR] Skip deactivation of EH-only cleanups when exceptions are disabled (PR #231334)

via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 12 16:58:46 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clangir

@llvm/pr-subscribers-clang

Author: Andy Kaylor (andykaylor)

<details>
<summary>Changes</summary>

When exceptions are disabled, we can get into a state where we pushed an EH-only cleanup to the EH stack but cleared the EHCleanup kind bit (because cleanups are disabled). Normally, these are just ignored as we pop them from the stack, but when such a cleanup is a temporary requiring delayed deactivation it isn't at the top of the stack and we try to deactivate it without removing it from the stack. Because the cleanup isn't needed, we just ignore it rather than setting up a deactivation for it.

Assisted-by: Cursor / various models

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


2 Files Affected:

- (modified) clang/lib/CIR/CodeGen/CIRGenCleanup.cpp (+6-2) 
- (added) clang/test/CIR/CodeGen/new-delete-no-exceptions.cpp (+51) 


``````````diff
diff --git a/clang/lib/CIR/CodeGen/CIRGenCleanup.cpp b/clang/lib/CIR/CodeGen/CIRGenCleanup.cpp
index 7a703b84bb04f..8e18cc7c0ca61 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCleanup.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCleanup.cpp
@@ -557,8 +557,12 @@ static void setupCleanupBlockDeactivation(CIRGenFunction &cgf,
                                           mlir::Operation *dominatingIP) {
   EHCleanupScope &scope = cast<EHCleanupScope>(*cgf.ehStack.find(c));
 
-  assert((scope.isNormalCleanup() || scope.isEHCleanup()) &&
-         "cleanup block is neither normal nor EH?");
+  // An EH-only cleanup has both flags clear when pushCleanup dropped
+  // the EH flag. That happens when exceptions are disabled, and when
+  // the innermost EH scope is a terminate scope. The cleanup never
+  // runs, so there is no active flag to clear.
+  if (!scope.isNormalCleanup() && !scope.isEHCleanup())
+    return;
 
   scope.setTestFlagInNormalCleanup(scope.isNormalCleanup());
   scope.setTestFlagInEHCleanup(scope.isEHCleanup());
diff --git a/clang/test/CIR/CodeGen/new-delete-no-exceptions.cpp b/clang/test/CIR/CodeGen/new-delete-no-exceptions.cpp
new file mode 100644
index 0000000000000..0f53a6562aef4
--- /dev/null
+++ b/clang/test/CIR/CodeGen/new-delete-no-exceptions.cpp
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 -no-enable-noundef-analysis %s -triple=x86_64-linux-gnu -fclangir -emit-cir -std=c++11 -o %t.cir
+// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s \
+// RUN:   --implicit-check-not=cleanup.isactive \
+// RUN:   --implicit-check-not="cleanup eh" \
+// RUN:   --implicit-check-not=@_ZdlPv
+// RUN: %clang_cc1 -no-enable-noundef-analysis %s -triple=x86_64-linux-gnu -fclangir -emit-llvm -std=c++11 -o %t-cir.ll
+// RUN: FileCheck --check-prefix=LLVM --input-file=%t-cir.ll %s \
+// RUN:   --implicit-check-not=personality \
+// RUN:   --implicit-check-not=invoke \
+// RUN:   --implicit-check-not=landingpad \
+// RUN:   --implicit-check-not=@_ZdlPv
+// RUN: %clang_cc1 -no-enable-noundef-analysis %s -triple=x86_64-linux-gnu -emit-llvm -std=c++11 -o %t.ll
+// RUN: FileCheck --check-prefix=LLVM --input-file=%t.ll %s \
+// RUN:   --implicit-check-not=personality \
+// RUN:   --implicit-check-not=invoke \
+// RUN:   --implicit-check-not=landingpad \
+// RUN:   --implicit-check-not=@_ZdlPv
+
+struct A {
+  A(int);
+  ~A();
+};
+
+struct B {
+  B();
+  ~B();
+  operator int();
+};
+
+B makeB();
+
+A *noex_new() { return new A(makeB()); }
+
+// CIR-LABEL: cir.func {{.*}} @_Z8noex_newv()
+// CIR:   cir.call @_Znwm({{.*}}) {{{.*}}builtin}
+// CIR:   cir.call @_Z5makeBv
+// CIR:   cir.cleanup.scope {
+// CIR:     cir.call @_ZN1BcviEv
+// CIR:     cir.call @_ZN1AC1Ei
+// CIR:   } cleanup normal {
+// CIR:     cir.call @_ZN1BD1Ev{{.*}} nothrow
+// CIR:   }
+// CIR:   cir.return
+
+// LLVM-LABEL: define {{.*}} @_Z8noex_newv()
+// LLVM:   call {{.*}} @_Znwm(i64 1)
+// LLVM:   call void @_Z5makeBv
+// LLVM:   call i32 @_ZN1BcviEv
+// LLVM:   call void @_ZN1AC1Ei
+// LLVM:   call void @_ZN1BD1Ev
+// LLVM:   ret ptr

``````````

</details>


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


More information about the cfe-commits mailing list