[clang] [CIR] Represent Cleanups with Cleanup scopes (PR #180276)

Andy Kaylor via cfe-commits cfe-commits at lists.llvm.org
Wed Feb 18 14:02:07 PST 2026


================
@@ -214,13 +256,26 @@ bool EHScopeStack::requiresCatchOrCleanup() const {
   return false;
 }
 
-static void emitCleanup(CIRGenFunction &cgf, EHScopeStack::Cleanup *cleanup,
+static void emitCleanup(CIRGenFunction &cgf, cir::CleanupScopeOp cleanupScope,
+                        EHScopeStack::Cleanup *cleanup,
                         EHScopeStack::Cleanup::Flags flags) {
+  CIRGenBuilderTy &builder = cgf.getBuilder();
+  mlir::Block &block = cleanupScope.getCleanupRegion().back();
+
+  mlir::OpBuilder::InsertionGuard guard(builder);
+  builder.setInsertionPointToStart(&block);
+
   // Ask the cleanup to emit itself.
   assert(cgf.haveInsertPoint() && "expected insertion point");
   assert(!cir::MissingFeatures::ehCleanupActiveFlag());
   cleanup->emit(cgf, flags);
   assert(cgf.haveInsertPoint() && "cleanup ended with no insertion point?");
+
+  if (block.empty() || !block.back().hasTrait<mlir::OpTrait::IsTerminator>()) {
----------------
andykaylor wrote:

This seems to be assuming that the emitted cleanup will have a single block. That may be true in practice, but I'd like to see an assertion to guard that assumption. It might be better to call `cleanupScope.getCleanupRegion().back()` again here, in case the emitted cleanup created multiple blocks.

The one case I could think of that might create multiple blocks is the NRVO cleanup, but I see that it is creating a `cir.if` statement rather than branching, so I think a single region with a single block is something we can expect.

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


More information about the cfe-commits mailing list