@@ -1280,6 +1280,70 @@ static bool EmitObjectDelete(CIRGenFunction &CGF, const CXXDeleteExpr *DE,
12801280 return false ;
12811281}
12821282
1283+ namespace {
1284+ // / Calls the given 'operator delete' on an array of objects.
1285+ struct CallArrayDelete final : EHScopeStack::Cleanup {
1286+ mlir::Value Ptr;
1287+ const FunctionDecl *OperatorDelete;
1288+ mlir::Value NumElements;
1289+ QualType ElementType;
1290+ CharUnits CookieSize;
1291+
1292+ CallArrayDelete (mlir::Value Ptr, const FunctionDecl *OperatorDelete,
1293+ mlir::Value NumElements, QualType ElementType,
1294+ CharUnits CookieSize)
1295+ : Ptr(Ptr), OperatorDelete(OperatorDelete), NumElements(NumElements),
1296+ ElementType (ElementType), CookieSize(CookieSize) {}
1297+
1298+ void Emit (CIRGenFunction &CGF, Flags flags) override {
1299+ CGF.emitDeleteCall (OperatorDelete, Ptr, ElementType, NumElements,
1300+ CookieSize);
1301+ }
1302+ };
1303+ } // namespace
1304+
1305+ // / Emit the code for deleting an array of objects.
1306+ static void EmitArrayDelete (CIRGenFunction &CGF, const CXXDeleteExpr *E,
1307+ Address deletedPtr, QualType elementType) {
1308+ llvm::Value *numElements = nullptr ;
1309+ llvm::Value *allocatedPtr = nullptr ;
1310+ CharUnits cookieSize;
1311+ CGF.CGM .getCXXABI ().ReadArrayCookie (CGF, deletedPtr, E, elementType,
1312+ numElements, allocatedPtr, cookieSize);
1313+
1314+ assert (allocatedPtr && " ReadArrayCookie didn't set allocated pointer" );
1315+
1316+ // Make sure that we call delete even if one of the dtors throws.
1317+ const FunctionDecl *operatorDelete = E->getOperatorDelete ();
1318+ CGF.EHStack .pushCleanup <CallArrayDelete>(NormalAndEHCleanup, allocatedPtr,
1319+ operatorDelete, numElements,
1320+ elementType, cookieSize);
1321+
1322+ // Destroy the elements.
1323+ if (QualType::DestructionKind dtorKind = elementType.isDestructedType ()) {
1324+ assert (numElements && " no element count for a type with a destructor!" );
1325+
1326+ CharUnits elementSize = CGF.getContext ().getTypeSizeInChars (elementType);
1327+ CharUnits elementAlign =
1328+ deletedPtr.getAlignment ().alignmentOfArrayElement (elementSize);
1329+
1330+ mlir::Value arrayBegin = deletedPtr.emitRawPointer ();
1331+ mlir::Value arrayEnd = CGF.Builder .createInBoundsGEP (
1332+ deletedPtr.getElementType (), arrayBegin, numElements, " delete.end" );
1333+
1334+ // Note that it is legal to allocate a zero-length array, and we
1335+ // can never fold the check away because the length should always
1336+ // come from a cookie.
1337+ CGF.emitArrayDestroy (arrayBegin, arrayEnd, elementType, elementAlign,
1338+ CGF.getDestroyer (dtorKind),
1339+ /* checkZeroLength*/ true ,
1340+ CGF.needsEHCleanup (dtorKind));
1341+ }
1342+
1343+ // Pop the cleanup block.
1344+ CGF.PopCleanupBlock ();
1345+ }
1346+
12831347void CIRGenFunction::emitCXXDeleteExpr (const CXXDeleteExpr *E) {
12841348 const Expr *Arg = E->getArgument ();
12851349 Address Ptr = emitPointerWithAlignment (Arg);
@@ -1319,6 +1383,7 @@ void CIRGenFunction::emitCXXDeleteExpr(const CXXDeleteExpr *E) {
13191383 assert (convertTypeForMem (DeleteTy) == Ptr.getElementType ());
13201384
13211385 if (E->isArrayForm ()) {
1386+ EmitArrayDelete (*this , E, Ptr, DeleteTy);
13221387 cir::DeleteArrayOp::create (builder, Ptr.getPointer ().getLoc (),
13231388 Ptr.getPointer ());
13241389 } else {
0 commit comments