aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CGClass.cpp
diff options
context:
space:
mode:
authorHans Wennborg <hans@chromium.org>2025-03-12 16:18:07 +0100
committerHans Wennborg <hans@chromium.org>2025-03-12 16:26:00 +0100
commite11ede5e90ee193dde179fe1a9ac9af718ede3db (patch)
treed719a4919d44cc8f4a5665a199a96bf98863b711 /clang/lib/CodeGen/CGClass.cpp
parent90a8322399c7beb021cfe704003d36fafb1a7d29 (diff)
downloadllvm-e11ede5e90ee193dde179fe1a9ac9af718ede3db.zip
llvm-e11ede5e90ee193dde179fe1a9ac9af718ede3db.tar.gz
llvm-e11ede5e90ee193dde179fe1a9ac9af718ede3db.tar.bz2
Revert "[MS][clang] Add support for vector deleting destructors (#126240)"
This caused link errors when building with sancov. See comment on the PR. > Whereas it is UB in terms of the standard to delete an array of objects > via pointer whose static type doesn't match its dynamic type, MSVC > supports an extension allowing to do it. > Aside from array deletion not working correctly in the mentioned case, > currently not having this extension implemented causes clang to generate > code that is not compatible with the code generated by MSVC, because > clang always puts scalar deleting destructor to the vftable. This PR > aims to resolve these problems. > > Fixes https://github.com/llvm/llvm-project/issues/19772 This reverts commit d6942d54f677000cf713d2b0eba57b641452beb4.
Diffstat (limited to 'clang/lib/CodeGen/CGClass.cpp')
-rw-r--r--clang/lib/CodeGen/CGClass.cpp77
1 files changed, 4 insertions, 73 deletions
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index e54fd54..fa69caa4 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -1433,70 +1433,6 @@ 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();
- CGF.EmitDeleteCall(Dtor->getOperatorDelete(), allocatedPtr,
- CGF.getContext().getTagDeclType(ClassDecl));
-
- CGF.EmitBranchThroughCleanup(CGF.ReturnBlock);
- CGF.EmitBlock(ScalarBB);
-}
-
/// EmitDestructorBody - Emits the body of the current destructor.
void CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) {
const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CurGD.getDecl());
@@ -1526,9 +1462,7 @@ void CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) {
// outside of the function-try-block, which means it's always
// possible to delegate the destructor body to the complete
// destructor. Do so.
- if (DtorType == Dtor_Deleting || DtorType == Dtor_VectorDeleting) {
- if (CXXStructorImplicitParamValue && DtorType == Dtor_VectorDeleting)
- EmitConditionalArrayDtorCall(Dtor, *this, CXXStructorImplicitParamValue);
+ if (DtorType == Dtor_Deleting) {
RunCleanupsScope DtorEpilogue(*this);
EnterDtorCleanups(Dtor, Dtor_Deleting);
if (HaveInsertPoint()) {
@@ -1557,8 +1491,6 @@ void CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) {
switch (DtorType) {
case Dtor_Comdat: llvm_unreachable("not expecting a COMDAT");
case Dtor_Deleting: llvm_unreachable("already handled deleting case");
- case Dtor_VectorDeleting:
- llvm_unreachable("already handled vector deleting case");
case Dtor_Complete:
assert((Body || getTarget().getCXXABI().isMicrosoft()) &&
@@ -1641,6 +1573,7 @@ namespace {
return CGF.EmitScalarExpr(ThisArg);
return CGF.LoadCXXThis();
}
+
/// Call the operator delete associated with the current destructor.
struct CallDtorDelete final : EHScopeStack::Cleanup {
CallDtorDelete() {}
@@ -1659,10 +1592,8 @@ namespace {
bool ReturnAfterDelete) {
llvm::BasicBlock *callDeleteBB = CGF.createBasicBlock("dtor.call_delete");
llvm::BasicBlock *continueBB = CGF.createBasicBlock("dtor.continue");
- auto *CondTy = cast<llvm::IntegerType>(ShouldDeleteCondition->getType());
- llvm::Value *CheckTheBit = CGF.Builder.CreateAnd(
- ShouldDeleteCondition, llvm::ConstantInt::get(CondTy, 1));
- llvm::Value *ShouldCallDelete = CGF.Builder.CreateIsNull(CheckTheBit);
+ llvm::Value *ShouldCallDelete
+ = CGF.Builder.CreateIsNull(ShouldDeleteCondition);
CGF.Builder.CreateCondBr(ShouldCallDelete, continueBB, callDeleteBB);
CGF.EmitBlock(callDeleteBB);