[clang] [CIR] Implement EH handling for field initializers (PR #192360)

Andy Kaylor via cfe-commits cfe-commits at lists.llvm.org
Thu Apr 16 09:24:52 PDT 2026


================
@@ -1071,6 +1071,17 @@ void CIRGenFunction::pushIrregularPartialArrayCleanup(mlir::Value arrayBegin,
       destroyer);
 }
 
+/// pushEHDestroy - Push the standard destructor for the given type as
+/// an EH-only cleanup.
+void CIRGenFunction::pushEHDestroy(QualType::DestructionKind dtorKind,
----------------
andykaylor wrote:

I looked at classic codegen to see all the places this is called there. It's called from `EmitInitializerForField` (as it is here), `EmitMemberInitializer` (which sounds like the same thing but is called in two places from `ConstructorMemcpyizer`), and `ConstructorMemcpyizer::pushEHDestructors`. It's this last use that leads to the check being outside of this function, as it's calling it in a loop that does something additional if the object needs destruction:
```
    for (unsigned i = 0; i < AggregatedInits.size(); ++i) {
      CXXCtorInitializer *MemberInit = AggregatedInits[i];
      QualType FieldType = MemberInit->getAnyMember()->getType();
      QualType::DestructionKind dtorKind = FieldType.isDestructedType();
      if (!CGF.needsEHCleanup(dtorKind))
        continue;
      LValue FieldLHS = LHS;
      EmitLValueForAnyFieldInitialization(CGF, MemberInit, FieldLHS);
      CGF.pushEHDestroy(dtorKind, FieldLHS.getAddress(), FieldType);
    }
```
For now, we've chosen not to implement `ConstructorMemcpyizer`, favoring more explicit initialization instead, so the current use could potentially be the only one, but I think the pattern above at least demonstrates the theoretical usefulness of the caller performing the check rather than doing it in this function. On the other hand, if the dtor kind doesn't need EH cleanup, the call to `getDestroyer` will hit an `llvm_unreachable`, so it's a bit stronger than an assert in practice, which I guess makes a case for making the check here.

It's a relatively cheap check, so even if we needed to do it twice, as in the `pushEHDestructors` case, it wouldn't be a big deal. I think I've convinced myself to move the check into this function.

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


More information about the cfe-commits mailing list