================
@@ -1442,6 +1442,103 @@ static bool
CanSkipVTablePointerInitialization(CodeGenFunction &CGF,
return true;
}
+static void EmitConditionalArrayDtorCall(const CXXDestructorDecl *DD,
+ CodeGenFunction &CGF,
+ llvm::Value *ShouldDeleteCondition) {
+ Address ThisPtr = CGF.LoadCXXThisAddress();
+ llvm::BasicBlock *ScalarBB = CGF.createBasicBlock("dtor.scalar");
+ llvm::BasicBlock *callDeleteBB =
+ CGF.createBasicBlock("dtor.call_delete_after_array_destroy");
+ llvm::BasicBlock *VectorBB = CGF.createBasicBlock("dtor.vector");
+ auto *CondTy = cast<llvm::IntegerType>(ShouldDeleteCondition->getType());
+ llvm::Value *CheckTheBitForArrayDestroy = CGF.Builder.CreateAnd(
+ ShouldDeleteCondition, llvm::ConstantInt::get(CondTy, 2));
+ llvm::Value *ShouldDestroyArray =
+ CGF.Builder.CreateIsNull(CheckTheBitForArrayDestroy);
+ CGF.Builder.CreateCondBr(ShouldDestroyArray, ScalarBB, VectorBB);
+
+ CGF.EmitBlock(VectorBB);
+
+ llvm::Value *numElements = nullptr;
+ llvm::Value *allocatedPtr = nullptr;
+ CharUnits cookieSize;
+ QualType EltTy = DD->getThisType()->getPointeeType();
+ CGF.CGM.getCXXABI().ReadArrayCookie(CGF, ThisPtr, EltTy, numElements,
+ allocatedPtr, cookieSize);
+
+ // Destroy the elements.
+ QualType::DestructionKind dtorKind = EltTy.isDestructedType();
+
+ assert(dtorKind);
+ assert(numElements && "no element count for a type with a destructor!");
+
+ CharUnits elementSize = CGF.getContext().getTypeSizeInChars(EltTy);
+ CharUnits elementAlign =
+ ThisPtr.getAlignment().alignmentOfArrayElement(elementSize);
+
+ llvm::Value *arrayBegin = ThisPtr.emitRawPointer(CGF);
+ llvm::Value *arrayEnd = CGF.Builder.CreateInBoundsGEP(
+ ThisPtr.getElementType(), arrayBegin, numElements, "delete.end");
+
+ // We already checked that the array is not 0-length before entering vector
+ // deleting dtor.
+ CGF.emitArrayDestroy(arrayBegin, arrayEnd, EltTy, elementAlign,
+ CGF.getDestroyer(dtorKind),
+ /*checkZeroLength*/ false,
CGF.needsEHCleanup(dtorKind));
+
+ llvm::BasicBlock *VectorBBCont = CGF.createBasicBlock("dtor.vector.cont");
+ CGF.EmitBlock(VectorBBCont);
+
+ llvm::Value *CheckTheBitForDeleteCall = CGF.Builder.CreateAnd(
+ ShouldDeleteCondition, llvm::ConstantInt::get(CondTy, 1));
+
+ llvm::Value *ShouldCallDelete =
+ CGF.Builder.CreateIsNull(CheckTheBitForDeleteCall);
+ CGF.Builder.CreateCondBr(ShouldCallDelete, CGF.ReturnBlock.getBlock(),
+ callDeleteBB);
+ CGF.EmitBlock(callDeleteBB);
+ const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CGF.CurCodeDecl);
+ const CXXRecordDecl *ClassDecl = Dtor->getParent();
+ if (Dtor->getArrayOperatorDelete()) {
+ if (!Dtor->getGlobalArrayOperatorDelete()) {
+ CGF.EmitDeleteCall(Dtor->getArrayOperatorDelete(), allocatedPtr,
+ CGF.getContext().getCanonicalTagType(ClassDecl));
+ } else {
+ // If global operator[] is set, the class had its own operator delete[].
+ // In that case, check the 4th bit. If it is set, we need to call
+ // ::delete[].
+ llvm::Value *CheckTheBitForGlobDeleteCall = CGF.Builder.CreateAnd(
+ ShouldDeleteCondition, llvm::ConstantInt::get(CondTy, 4));
+
+ llvm::Value *ShouldCallGlobDelete =
+ CGF.Builder.CreateIsNull(CheckTheBitForGlobDeleteCall);
+ llvm::BasicBlock *GlobDelete =
+ CGF.createBasicBlock("dtor.call_glob_delete_after_array_destroy");
+ llvm::BasicBlock *ClassDelete =
+ CGF.createBasicBlock("dtor.call_class_delete_after_array_destroy");
+ CGF.Builder.CreateCondBr(ShouldCallGlobDelete, ClassDelete, GlobDelete);
+ CGF.EmitBlock(ClassDelete);
+ CGF.EmitDeleteCall(Dtor->getArrayOperatorDelete(), allocatedPtr,
+ CGF.getContext().getCanonicalTagType(ClassDecl));
+ CGF.EmitBranchThroughCleanup(CGF.ReturnBlock);
+
+ CGF.EmitBlock(GlobDelete);
+ CGF.EmitDeleteCall(Dtor->getGlobalArrayOperatorDelete(), allocatedPtr,
+ CGF.getContext().getCanonicalTagType(ClassDecl));
----------------
zmodem wrote:
Do we need to pass NumElements and CookieSize here, similarly to
https://github.com/llvm/llvm-project/blob/ed5589b0dcec40e25675812a330e171ed0587644/clang/lib/CodeGen/CGExprCXX.cpp#L2030-L2031
https://github.com/llvm/llvm-project/pull/170337
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits