[clang] [win][clang] Align scalar deleting destructors with MSABI (PR #139566)
Mariya Podchishchaeva via cfe-commits
cfe-commits at lists.llvm.org
Wed Jun 11 09:50:02 PDT 2025
================
@@ -1589,25 +1589,74 @@ namespace {
void EmitConditionalDtorDeleteCall(CodeGenFunction &CGF,
llvm::Value *ShouldDeleteCondition,
bool ReturnAfterDelete) {
+ const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CGF.CurCodeDecl);
+ const CXXRecordDecl *ClassDecl = Dtor->getParent();
+ const FunctionDecl *OD = Dtor->getOperatorDelete();
+ assert(OD->isDestroyingOperatorDelete() == ReturnAfterDelete &&
+ "unexpected value for ReturnAfterDelete");
+ auto *CondTy = cast<llvm::IntegerType>(ShouldDeleteCondition->getType());
+ if (OD->isDestroyingOperatorDelete()) {
+ llvm::BasicBlock *CallDtor = CGF.createBasicBlock("dtor.call_dtor");
+ llvm::BasicBlock *DontCallDtor = CGF.createBasicBlock("dtor.entry_cont");
+ // Third bit set signals that global operator delete is called. That means
+ // despite class having destroying operator delete which is responsible
+ // for calling dtor, we need to call dtor because global operator delete
+ // won't do that.
+ llvm::Value *Check3rdBit = CGF.Builder.CreateAnd(
+ ShouldDeleteCondition, llvm::ConstantInt::get(CondTy, 4));
+ llvm::Value *ShouldCallDtor = CGF.Builder.CreateIsNull(Check3rdBit);
+ CGF.Builder.CreateCondBr(ShouldCallDtor, DontCallDtor, CallDtor);
+ CGF.EmitBlock(CallDtor);
+ QualType ThisTy = Dtor->getFunctionObjectParameterType();
+ CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete, /*ForVirtualBase=*/false,
+ /*Delegating=*/false, CGF.LoadCXXThisAddress(),
+ ThisTy);
+ CGF.Builder.CreateBr(DontCallDtor);
+ CGF.EmitBlock(DontCallDtor);
+ }
llvm::BasicBlock *callDeleteBB = CGF.createBasicBlock("dtor.call_delete");
llvm::BasicBlock *continueBB = CGF.createBasicBlock("dtor.continue");
- llvm::Value *ShouldCallDelete
- = CGF.Builder.CreateIsNull(ShouldDeleteCondition);
+ // First bit set signals that operator delete must be called.
+ llvm::Value *Check1stBit = CGF.Builder.CreateAnd(
+ ShouldDeleteCondition, llvm::ConstantInt::get(CondTy, 1));
+ llvm::Value *ShouldCallDelete = CGF.Builder.CreateIsNull(Check1stBit);
CGF.Builder.CreateCondBr(ShouldCallDelete, continueBB, callDeleteBB);
CGF.EmitBlock(callDeleteBB);
- const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CGF.CurCodeDecl);
- const CXXRecordDecl *ClassDecl = Dtor->getParent();
- CGF.EmitDeleteCall(Dtor->getOperatorDelete(),
- LoadThisForDtorDelete(CGF, Dtor),
- CGF.getContext().getTagDeclType(ClassDecl));
- assert(Dtor->getOperatorDelete()->isDestroyingOperatorDelete() ==
- ReturnAfterDelete &&
- "unexpected value for ReturnAfterDelete");
- if (ReturnAfterDelete)
- CGF.EmitBranchThroughCleanup(CGF.ReturnBlock);
- else
- CGF.Builder.CreateBr(continueBB);
+ auto EmitDeleteAndGoToEnd = [&](const FunctionDecl *DeleteOp) {
+ CGF.EmitDeleteCall(DeleteOp, LoadThisForDtorDelete(CGF, Dtor),
+ CGF.getContext().getTagDeclType(ClassDecl));
+ if (ReturnAfterDelete)
+ CGF.EmitBranchThroughCleanup(CGF.ReturnBlock);
+ else
+ CGF.Builder.CreateBr(continueBB);
+ };
+ // If Sema only found a global operator delete previously, the dtor can
+ // always call it. Otherwise we need to check the third bit and call the
+ // appropriate operator delete, i.e. global or class-specific.
+ if (isa<CXXMethodDecl>(OD)) {
+ // Third bit set signals that global operator delete is called, i.e.
+ // ::delete appears on the callsite.
+ 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");
+ llvm::BasicBlock *ClassDelete =
+ CGF.createBasicBlock("dtor.call_class_delete");
+ CGF.Builder.CreateCondBr(ShouldCallGlobDelete, ClassDelete, GlobDelete);
+ CGF.EmitBlock(GlobDelete);
+
+ const FunctionDecl *GlobOD = Dtor->getOperatorGlobalDelete();
+ if (GlobOD)
+ EmitDeleteAndGoToEnd(GlobOD);
+ else
+ CGF.Builder.CreateUnreachable();
----------------
Fznamznon wrote:
Good point, thanks!
https://github.com/llvm/llvm-project/pull/139566
More information about the cfe-commits
mailing list