diff options
author | Mariya Podchishchaeva <mariya.podchishchaeva@intel.com> | 2025-04-14 14:17:36 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-04-14 14:17:36 +0200 |
commit | 88d0b0835d030635c5d08c9a9754c21b5ac00be9 (patch) | |
tree | 534b1f36839412f790133a5e3e00c889249758a6 /clang/lib/CodeGen | |
parent | fe54d1afcca055f464840654dd2ec3fd83aea688 (diff) | |
download | llvm-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.cpp | 37 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGCXXABI.cpp | 14 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGCXXABI.h | 7 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGClass.cpp | 77 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGDebugInfo.cpp | 3 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExprCXX.cpp | 42 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGVTables.cpp | 3 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 48 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.h | 6 | ||||
-rw-r--r-- | clang/lib/CodeGen/ItaniumCXXABI.cpp | 6 | ||||
-rw-r--r-- | clang/lib/CodeGen/MicrosoftCXXABI.cpp | 52 |
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())); |