aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
authorMariya Podchishchaeva <mariya.podchishchaeva@intel.com>2025-04-14 14:17:36 +0200
committerGitHub <noreply@github.com>2025-04-14 14:17:36 +0200
commit88d0b0835d030635c5d08c9a9754c21b5ac00be9 (patch)
tree534b1f36839412f790133a5e3e00c889249758a6 /clang/lib/CodeGen
parentfe54d1afcca055f464840654dd2ec3fd83aea688 (diff)
downloadllvm-88d0b0835d030635c5d08c9a9754c21b5ac00be9.zip
llvm-88d0b0835d030635c5d08c9a9754c21b5ac00be9.tar.gz
llvm-88d0b0835d030635c5d08c9a9754c21b5ac00be9.tar.bz2
[MS][clang] Revert vector deleting destructors support (#135611)
Finding operator delete[] is still problematic, without it the extension is a security hazard, so reverting until the problem with operator delete[] is figured out. This reverts the following PRs: Reland [MS][clang] Add support for vector deleting destructors (llvm#133451) [MS][clang] Make sure vector deleting dtor calls correct operator delete (llvm#133950) [MS][clang] Fix crash on deletion of array of pointers (llvm#134088) [clang] Do not diagnose unused deleted operator delete[] (llvm#134357) [MS][clang] Error about ambiguous operator delete[] only when required (llvm#135041)
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGCXX.cpp37
-rw-r--r--clang/lib/CodeGen/CGCXXABI.cpp14
-rw-r--r--clang/lib/CodeGen/CGCXXABI.h7
-rw-r--r--clang/lib/CodeGen/CGClass.cpp77
-rw-r--r--clang/lib/CodeGen/CGDebugInfo.cpp3
-rw-r--r--clang/lib/CodeGen/CGExprCXX.cpp42
-rw-r--r--clang/lib/CodeGen/CGVTables.cpp3
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp48
-rw-r--r--clang/lib/CodeGen/CodeGenModule.h6
-rw-r--r--clang/lib/CodeGen/ItaniumCXXABI.cpp6
-rw-r--r--clang/lib/CodeGen/MicrosoftCXXABI.cpp52
11 files changed, 26 insertions, 269 deletions
diff --git a/clang/lib/CodeGen/CGCXX.cpp b/clang/lib/CodeGen/CGCXX.cpp
index 6f47e24..78a7b02 100644
--- a/clang/lib/CodeGen/CGCXX.cpp
+++ b/clang/lib/CodeGen/CGCXX.cpp
@@ -175,6 +175,7 @@ bool CodeGenModule::TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D) {
// requires explicit comdat support in the IL.
if (llvm::GlobalValue::isWeakForLinker(TargetLinkage))
return true;
+
// Create the alias with no name.
auto *Alias = llvm::GlobalAlias::create(AliasValueType, 0, Linkage, "",
Aliasee, &getModule());
@@ -200,42 +201,6 @@ bool CodeGenModule::TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D) {
return false;
}
-/// Emit a definition as a global alias for another definition, unconditionally.
-void CodeGenModule::EmitDefinitionAsAlias(GlobalDecl AliasDecl,
- GlobalDecl TargetDecl) {
-
- llvm::Type *AliasValueType = getTypes().GetFunctionType(AliasDecl);
-
- StringRef MangledName = getMangledName(AliasDecl);
- llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
- if (Entry && !Entry->isDeclaration())
- return;
- auto *Aliasee = cast<llvm::GlobalValue>(GetAddrOfGlobal(TargetDecl));
-
- // Determine the linkage type for the alias.
- llvm::GlobalValue::LinkageTypes Linkage = getFunctionLinkage(AliasDecl);
-
- // Create the alias with no name.
- auto *Alias = llvm::GlobalAlias::create(AliasValueType, 0, Linkage, "",
- Aliasee, &getModule());
- // Destructors are always unnamed_addr.
- Alias->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
-
- if (Entry) {
- assert(Entry->getValueType() == AliasValueType &&
- Entry->getAddressSpace() == Alias->getAddressSpace() &&
- "declaration exists with different type");
- Alias->takeName(Entry);
- Entry->replaceAllUsesWith(Alias);
- Entry->eraseFromParent();
- } else {
- Alias->setName(MangledName);
- }
-
- // Set any additional necessary attributes for the alias.
- SetCommonAttributes(AliasDecl, Alias);
-}
-
llvm::Function *CodeGenModule::codegenCXXStructor(GlobalDecl GD) {
const CGFunctionInfo &FnInfo = getTypes().arrangeCXXStructorDeclaration(GD);
auto *Fn = cast<llvm::Function>(
diff --git a/clang/lib/CodeGen/CGCXXABI.cpp b/clang/lib/CodeGen/CGCXXABI.cpp
index 93dc17b..d42e0bb8 100644
--- a/clang/lib/CodeGen/CGCXXABI.cpp
+++ b/clang/lib/CodeGen/CGCXXABI.cpp
@@ -271,20 +271,6 @@ void CGCXXABI::ReadArrayCookie(CodeGenFunction &CGF, Address ptr,
numElements = readArrayCookieImpl(CGF, allocAddr, cookieSize);
}
-void CGCXXABI::ReadArrayCookie(CodeGenFunction &CGF, Address ptr,
- QualType eltTy, llvm::Value *&numElements,
- llvm::Value *&allocPtr, CharUnits &cookieSize) {
- assert(eltTy.isDestructedType());
-
- // Derive a char* in the same address space as the pointer.
- ptr = ptr.withElementType(CGF.Int8Ty);
-
- cookieSize = getArrayCookieSizeImpl(eltTy);
- Address allocAddr = CGF.Builder.CreateConstInBoundsByteGEP(ptr, -cookieSize);
- allocPtr = allocAddr.emitRawPointer(CGF);
- numElements = readArrayCookieImpl(CGF, allocAddr, cookieSize);
-}
-
llvm::Value *CGCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
Address ptr,
CharUnits cookieSize) {
diff --git a/clang/lib/CodeGen/CGCXXABI.h b/clang/lib/CodeGen/CGCXXABI.h
index da2d367..96fe046 100644
--- a/clang/lib/CodeGen/CGCXXABI.h
+++ b/clang/lib/CodeGen/CGCXXABI.h
@@ -275,7 +275,6 @@ public:
virtual CatchTypeInfo getCatchAllTypeInfo();
virtual bool shouldTypeidBeNullChecked(QualType SrcRecordTy) = 0;
- virtual bool hasVectorDeletingDtors() = 0;
virtual void EmitBadTypeidCall(CodeGenFunction &CGF) = 0;
virtual llvm::Value *EmitTypeid(CodeGenFunction &CGF, QualType SrcRecordTy,
Address ThisPtr,
@@ -576,12 +575,6 @@ public:
QualType ElementType, llvm::Value *&NumElements,
llvm::Value *&AllocPtr, CharUnits &CookieSize);
- /// Reads the array cookie associated with the given pointer,
- /// that should have one.
- void ReadArrayCookie(CodeGenFunction &CGF, Address Ptr, QualType ElementType,
- llvm::Value *&NumElements, llvm::Value *&AllocPtr,
- CharUnits &CookieSize);
-
/// Return whether the given global decl needs a VTT parameter.
virtual bool NeedsVTTParameter(GlobalDecl GD);
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index 0f2422a..1c73a5b 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -1429,70 +1429,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->getArrayOperatorDelete(), 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());
@@ -1522,9 +1458,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()) {
@@ -1553,8 +1487,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()) &&
@@ -1637,6 +1569,7 @@ namespace {
return CGF.EmitScalarExpr(ThisArg);
return CGF.LoadCXXThis();
}
+
/// Call the operator delete associated with the current destructor.
struct CallDtorDelete final : EHScopeStack::Cleanup {
CallDtorDelete() {}
@@ -1655,10 +1588,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);
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index d659243..367b51c 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -2119,8 +2119,7 @@ llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
// Emit MS ABI vftable information. There is only one entry for the
// deleting dtor.
const auto *DD = dyn_cast<CXXDestructorDecl>(Method);
- GlobalDecl GD =
- DD ? GlobalDecl(DD, Dtor_VectorDeleting) : GlobalDecl(Method);
+ GlobalDecl GD = DD ? GlobalDecl(DD, Dtor_Deleting) : GlobalDecl(Method);
MethodVFTableLocation ML =
CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
VIndex = ML.Index;
diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp
index a0d21a4..3e8c42d 100644
--- a/clang/lib/CodeGen/CGExprCXX.cpp
+++ b/clang/lib/CodeGen/CGExprCXX.cpp
@@ -1209,8 +1209,6 @@ void CodeGenFunction::EmitNewArrayInitializer(
EmitCXXAggrConstructorCall(Ctor, NumElements, CurPtr, CCE,
/*NewPointerIsChecked*/true,
CCE->requiresZeroInitialization());
- if (CGM.getCXXABI().hasVectorDeletingDtors())
- CGM.requireVectorDestructorDefinition(Ctor->getParent());
return;
}
@@ -1957,8 +1955,10 @@ static void EmitDestroyingObjectDelete(CodeGenFunction &CGF,
/// Emit the code for deleting a single object.
/// \return \c true if we started emitting UnconditionalDeleteBlock, \c false
/// if not.
-static bool EmitObjectDelete(CodeGenFunction &CGF, const CXXDeleteExpr *DE,
- Address Ptr, QualType ElementType,
+static bool EmitObjectDelete(CodeGenFunction &CGF,
+ const CXXDeleteExpr *DE,
+ Address Ptr,
+ QualType ElementType,
llvm::BasicBlock *UnconditionalDeleteBlock) {
// C++11 [expr.delete]p3:
// If the static type of the object to be deleted is different from its
@@ -2174,40 +2174,6 @@ void CodeGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *E) {
assert(ConvertTypeForMem(DeleteTy) == Ptr.getElementType());
- if (E->isArrayForm() && CGM.getCXXABI().hasVectorDeletingDtors()) {
- if (auto *RD = DeleteTy->getAsCXXRecordDecl()) {
- auto *Dtor = RD->getDestructor();
- if (Dtor && Dtor->isVirtual()) {
- llvm::Value *NumElements = nullptr;
- llvm::Value *AllocatedPtr = nullptr;
- CharUnits CookieSize;
- llvm::BasicBlock *bodyBB = createBasicBlock("vdtor.call");
- llvm::BasicBlock *doneBB = createBasicBlock("vdtor.nocall");
- // Check array cookie to see if the array has 0 length. Don't call
- // the destructor in that case.
- CGM.getCXXABI().ReadArrayCookie(*this, Ptr, E, DeleteTy, NumElements,
- AllocatedPtr, CookieSize);
-
- auto *CondTy = cast<llvm::IntegerType>(NumElements->getType());
- llvm::Value *isEmpty = Builder.CreateICmpEQ(
- NumElements, llvm::ConstantInt::get(CondTy, 0));
- Builder.CreateCondBr(isEmpty, doneBB, bodyBB);
-
- // Delete cookie for empty array.
- const FunctionDecl *operatorDelete = E->getOperatorDelete();
- EmitBlock(doneBB);
- EmitDeleteCall(operatorDelete, AllocatedPtr, DeleteTy, NumElements,
- CookieSize);
- EmitBranch(DeleteEnd);
-
- EmitBlock(bodyBB);
- if (!EmitObjectDelete(*this, E, Ptr, DeleteTy, DeleteEnd))
- EmitBlock(DeleteEnd);
- return;
- }
- }
- }
-
if (E->isArrayForm()) {
EmitArrayDelete(*this, E, Ptr, DeleteTy);
EmitBlock(DeleteEnd);
diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp
index 0a1cf24..8d0e8d1 100644
--- a/clang/lib/CodeGen/CGVTables.cpp
+++ b/clang/lib/CodeGen/CGVTables.cpp
@@ -770,8 +770,7 @@ void CodeGenVTables::addVTableComponent(ConstantArrayBuilder &builder,
case VTableComponent::CK_FunctionPointer:
case VTableComponent::CK_CompleteDtorPointer:
case VTableComponent::CK_DeletingDtorPointer: {
- GlobalDecl GD =
- component.getGlobalDecl(CGM.getCXXABI().hasVectorDeletingDtors());
+ GlobalDecl GD = component.getGlobalDecl();
const bool IsThunk =
nextVTableThunkIndex < layout.vtable_thunks().size() &&
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 0154799..4a48c2f 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -7948,51 +7948,3 @@ void CodeGenModule::moveLazyEmissionStates(CodeGenModule *NewBuilder) {
NewBuilder->ABI->MangleCtx = std::move(ABI->MangleCtx);
}
-
-bool CodeGenModule::classNeedsVectorDestructor(const CXXRecordDecl *RD) {
- CXXDestructorDecl *Dtor = RD->getDestructor();
- // The compiler can't know if new[]/delete[] will be used outside of the DLL,
- // so just force vector deleting destructor emission if dllexport is present.
- // This matches MSVC behavior.
- if (Dtor && Dtor->isVirtual() && Dtor->isDefined() &&
- Dtor->hasAttr<DLLExportAttr>())
- return true;
-
- assert(getCXXABI().hasVectorDeletingDtors());
- return RequireVectorDeletingDtor.count(RD);
-}
-
-void CodeGenModule::requireVectorDestructorDefinition(const CXXRecordDecl *RD) {
- assert(getCXXABI().hasVectorDeletingDtors());
- RequireVectorDeletingDtor.insert(RD);
-
- // To reduce code size in general case we lazily emit scalar deleting
- // destructor definition and an alias from vector deleting destructor to
- // scalar deleting destructor. It may happen that we first emitted the scalar
- // deleting destructor definition and the alias and then discovered that the
- // definition of the vector deleting destructor is required. Then we need to
- // remove the alias and the scalar deleting destructor and queue vector
- // deleting destructor body for emission. Check if that is the case.
- CXXDestructorDecl *DtorD = RD->getDestructor();
- GlobalDecl ScalarDtorGD(DtorD, Dtor_Deleting);
- StringRef MangledName = getMangledName(ScalarDtorGD);
- llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
- if (Entry && !Entry->isDeclaration()) {
- GlobalDecl VectorDtorGD(DtorD, Dtor_VectorDeleting);
- StringRef VDName = getMangledName(VectorDtorGD);
- llvm::GlobalValue *VDEntry = GetGlobalValue(VDName);
- // It exists and it should be an alias.
- assert(VDEntry && isa<llvm::GlobalAlias>(VDEntry));
- auto *NewFn = llvm::Function::Create(
- cast<llvm::FunctionType>(VDEntry->getValueType()),
- llvm::Function::ExternalLinkage, VDName, &getModule());
- SetFunctionAttributes(VectorDtorGD, NewFn, /*IsIncompleteFunction*/ false,
- /*IsThunk*/ false);
- NewFn->takeName(VDEntry);
- VDEntry->replaceAllUsesWith(NewFn);
- VDEntry->eraseFromParent();
- Entry->replaceAllUsesWith(NewFn);
- Entry->eraseFromParent();
- addDeferredDeclToEmit(VectorDtorGD);
- }
-}
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index 2cf15e2..46de3d86 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -528,9 +528,6 @@ private:
/// that we don't re-emit the initializer.
llvm::DenseMap<const Decl*, unsigned> DelayedCXXInitPosition;
- /// To remember which types did require a vector deleting dtor.
- llvm::SmallPtrSet<const CXXRecordDecl *, 16> RequireVectorDeletingDtor;
-
typedef std::pair<OrderGlobalInitsOrStermFinalizers, llvm::Function *>
GlobalInitData;
@@ -1545,7 +1542,6 @@ public:
void EmitGlobal(GlobalDecl D);
bool TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D);
- void EmitDefinitionAsAlias(GlobalDecl Alias, GlobalDecl Target);
llvm::GlobalValue *GetGlobalValue(StringRef Ref);
@@ -1813,8 +1809,6 @@ public:
// behavior. So projects like the Linux kernel can rely on it.
return !getLangOpts().CPlusPlus;
}
- void requireVectorDestructorDefinition(const CXXRecordDecl *RD);
- bool classNeedsVectorDestructor(const CXXRecordDecl *RD);
private:
bool shouldDropDLLAttribute(const Decl *D, const llvm::GlobalValue *GV) const;
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index 35485dc..70b53be 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -91,8 +91,6 @@ public:
case Dtor_Comdat:
llvm_unreachable("emitting dtor comdat as function?");
- case Dtor_VectorDeleting:
- llvm_unreachable("unexpected dtor kind for this ABI");
}
llvm_unreachable("bad dtor kind");
}
@@ -181,7 +179,6 @@ public:
}
bool shouldTypeidBeNullChecked(QualType SrcRecordTy) override;
- bool hasVectorDeletingDtors() override { return false; }
void EmitBadTypeidCall(CodeGenFunction &CGF) override;
llvm::Value *EmitTypeid(CodeGenFunction &CGF, QualType SrcRecordTy,
Address ThisPtr,
@@ -451,8 +448,7 @@ public:
if (!IsInlined)
continue;
- StringRef Name = CGM.getMangledName(
- VtableComponent.getGlobalDecl(/*HasVectorDeletingDtors=*/false));
+ StringRef Name = CGM.getMangledName(VtableComponent.getGlobalDecl());
auto *Entry = CGM.GetGlobalValue(Name);
// This checks if virtual inline function has already been emitted.
// Note that it is possible that this inline function would be emitted
diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
index 93ca870..aa9a55a 100644
--- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -71,8 +71,8 @@ public:
switch (GD.getDtorType()) {
case Dtor_Complete:
case Dtor_Deleting:
- case Dtor_VectorDeleting:
return true;
+
case Dtor_Base:
return false;
@@ -146,7 +146,6 @@ public:
}
bool shouldTypeidBeNullChecked(QualType SrcRecordTy) override;
- bool hasVectorDeletingDtors() override { return true; }
void EmitBadTypeidCall(CodeGenFunction &CGF) override;
llvm::Value *EmitTypeid(CodeGenFunction &CGF, QualType SrcRecordTy,
Address ThisPtr,
@@ -262,7 +261,7 @@ public:
// There's only Dtor_Deleting in vftable but it shares the this
// adjustment with the base one, so look up the deleting one instead.
- LookupGD = GlobalDecl(DD, Dtor_VectorDeleting);
+ LookupGD = GlobalDecl(DD, Dtor_Deleting);
}
MethodVFTableLocation ML =
CGM.getMicrosoftVTableContext().getMethodVFTableLocation(LookupGD);
@@ -344,8 +343,8 @@ public:
void adjustCallArgsForDestructorThunk(CodeGenFunction &CGF, GlobalDecl GD,
CallArgList &CallArgs) override {
- assert(GD.getDtorType() == Dtor_VectorDeleting &&
- "Only vector deleting destructor thunks are available in this ABI");
+ assert(GD.getDtorType() == Dtor_Deleting &&
+ "Only deleting destructor thunks are available in this ABI");
CallArgs.add(RValue::get(getStructorImplicitParamValue(CGF)),
getContext().IntTy);
}
@@ -1092,8 +1091,7 @@ bool MicrosoftCXXABI::HasThisReturn(GlobalDecl GD) const {
static bool isDeletingDtor(GlobalDecl GD) {
return isa<CXXDestructorDecl>(GD.getDecl()) &&
- (GD.getDtorType() == Dtor_Deleting ||
- GD.getDtorType() == Dtor_VectorDeleting);
+ GD.getDtorType() == Dtor_Deleting;
}
bool MicrosoftCXXABI::hasMostDerivedReturn(GlobalDecl GD) const {
@@ -1346,8 +1344,7 @@ MicrosoftCXXABI::buildStructorSignature(GlobalDecl GD,
AddedStructorArgCounts Added;
// TODO: 'for base' flag
if (isa<CXXDestructorDecl>(GD.getDecl()) &&
- (GD.getDtorType() == Dtor_Deleting ||
- GD.getDtorType() == Dtor_VectorDeleting)) {
+ GD.getDtorType() == Dtor_Deleting) {
// The scalar deleting destructor takes an implicit int parameter.
ArgTys.push_back(getContext().IntTy);
++Added.Suffix;
@@ -1379,7 +1376,7 @@ void MicrosoftCXXABI::setCXXDestructorDLLStorage(llvm::GlobalValue *GV,
CXXDtorType DT) const {
// Deleting destructor variants are never imported or exported. Give them the
// default storage class.
- if (DT == Dtor_Deleting || DT == Dtor_VectorDeleting) {
+ if (DT == Dtor_Deleting) {
GV->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
} else {
const NamedDecl *ND = Dtor;
@@ -1413,12 +1410,6 @@ llvm::GlobalValue::LinkageTypes MicrosoftCXXABI::getCXXDestructorLinkage(
// and are emitted everywhere they are used. They are internal if the class
// is internal.
return llvm::GlobalValue::LinkOnceODRLinkage;
- case Dtor_VectorDeleting:
- // Use the weak, non-ODR linkage for vector deleting destructors to block
- // inlining. This enables an MS ABI code-size saving optimization that
- // allows us to avoid emitting array deletion code when arrays of a given
- // type are not allocated within the final linkage unit.
- return llvm::GlobalValue::WeakAnyLinkage;
case Dtor_Comdat:
llvm_unreachable("MS C++ ABI does not support comdat dtors");
}
@@ -1450,7 +1441,7 @@ MicrosoftCXXABI::getVirtualFunctionPrologueThisAdjustment(GlobalDecl GD) {
// There's no Dtor_Base in vftable but it shares the this adjustment with
// the deleting one, so look it up instead.
- GD = GlobalDecl(DD, Dtor_VectorDeleting);
+ GD = GlobalDecl(DD, Dtor_Deleting);
}
MethodVFTableLocation ML =
@@ -1499,7 +1490,7 @@ Address MicrosoftCXXABI::adjustThisArgumentForVirtualFunctionCall(
// There's only Dtor_Deleting in vftable but it shares the this adjustment
// with the base one, so look up the deleting one instead.
- LookupGD = GlobalDecl(DD, Dtor_VectorDeleting);
+ LookupGD = GlobalDecl(DD, Dtor_Deleting);
}
MethodVFTableLocation ML =
CGM.getMicrosoftVTableContext().getMethodVFTableLocation(LookupGD);
@@ -2012,20 +2003,20 @@ llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall(
auto *D = dyn_cast<const CXXDeleteExpr *>(E);
assert((CE != nullptr) ^ (D != nullptr));
assert(CE == nullptr || CE->arg_begin() == CE->arg_end());
- assert(DtorType == Dtor_VectorDeleting || DtorType == Dtor_Complete ||
- DtorType == Dtor_Deleting);
+ assert(DtorType == Dtor_Deleting || DtorType == Dtor_Complete);
// We have only one destructor in the vftable but can get both behaviors
// by passing an implicit int parameter.
- GlobalDecl GD(Dtor, Dtor_VectorDeleting);
+ GlobalDecl GD(Dtor, Dtor_Deleting);
const CGFunctionInfo *FInfo =
&CGM.getTypes().arrangeCXXStructorDeclaration(GD);
llvm::FunctionType *Ty = CGF.CGM.getTypes().GetFunctionType(*FInfo);
CGCallee Callee = CGCallee::forVirtual(CE, GD, This, Ty);
ASTContext &Context = getContext();
- uint32_t Flags = ((D && D->isArrayForm()) << 1) | (DtorType == Dtor_Deleting);
- llvm::Value *ImplicitParam = CGF.Builder.getInt32(Flags);
+ llvm::Value *ImplicitParam = llvm::ConstantInt::get(
+ llvm::IntegerType::getInt32Ty(CGF.getLLVMContext()),
+ DtorType == Dtor_Deleting);
QualType ThisTy;
if (CE) {
@@ -2034,9 +2025,6 @@ llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall(
ThisTy = D->getDestroyedType();
}
- while (const ArrayType *ATy = Context.getAsArrayType(ThisTy))
- ThisTy = ATy->getElementType();
-
This = adjustThisArgumentForVirtualFunctionCall(CGF, GD, This, true);
RValue RV =
CGF.EmitCXXDestructorCall(GD, Callee, This.emitRawPointer(CGF), ThisTy,
@@ -4070,18 +4058,6 @@ void MicrosoftCXXABI::emitCXXStructor(GlobalDecl GD) {
if (GD.getDtorType() == Dtor_Base && !CGM.TryEmitBaseDestructorAsAlias(dtor))
return;
- if (GD.getDtorType() == Dtor_VectorDeleting &&
- !CGM.classNeedsVectorDestructor(dtor->getParent())) {
- // Create GlobalDecl object with the correct type for the scalar
- // deleting destructor.
- GlobalDecl ScalarDtorGD(dtor, Dtor_Deleting);
-
- // Emit an alias from the vector deleting destructor to the scalar deleting
- // destructor.
- CGM.EmitDefinitionAsAlias(GD, ScalarDtorGD);
- return;
- }
-
llvm::Function *Fn = CGM.codegenCXXStructor(GD);
if (Fn->isWeakForLinker())
Fn->setComdat(CGM.getModule().getOrInsertComdat(Fn->getName()));