llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-codegen Author: original-cooling-space (zhangweize9-cyber) <details> <summary>Changes</summary> This conservative PR fixes the inconsistency of behaviors of '-fno-use-cxa-atexit' to GCC, which blocks user to use .fini_array instead of __cxa_atexit() and atexit() on ELF-based platforms. This PR currently fixes this bug on the ELF-based platforms only, but perhaps also applicable on COFF. --- Patch is 70.00 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/216611.diff 1 Files Affected: - (modified) clang/lib/CodeGen/ItaniumCXXABI.cpp (+397-408) ``````````diff diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index 5c5fefe32c06c..ef20d8c871a4b 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -62,12 +62,10 @@ class ItaniumCXXABI : public CodeGen::CGCXXABI { } public: - ItaniumCXXABI(CodeGen::CodeGenModule &CGM, - bool UseARMMethodPtrABI = false, - bool UseARMGuardVarABI = false) : - CGCXXABI(CGM), UseARMMethodPtrABI(UseARMMethodPtrABI), - UseARMGuardVarABI(UseARMGuardVarABI), - Use32BitVTableOffsetABI(false) { } + ItaniumCXXABI(CodeGen::CodeGenModule &CGM, bool UseARMMethodPtrABI = false, + bool UseARMGuardVarABI = false) + : CGCXXABI(CGM), UseARMMethodPtrABI(UseARMMethodPtrABI), + UseARMGuardVarABI(UseARMGuardVarABI), Use32BitVTableOffsetABI(false) {} bool classifyReturnType(CGFunctionInfo &FI) const override; @@ -129,12 +127,10 @@ class ItaniumCXXABI : public CodeGen::CGCXXABI { llvm::Type *ConvertMemberPointerType(const MemberPointerType *MPT) override; CGCallee - EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF, - const Expr *E, - Address This, - llvm::Value *&ThisPtrForCall, - llvm::Value *MemFnPtr, - const MemberPointerType *MPT) override; + EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF, const Expr *E, + Address This, llvm::Value *&ThisPtrForCall, + llvm::Value *MemFnPtr, + const MemberPointerType *MPT) override; llvm::Value *EmitMemberDataPointerAddress(CodeGenFunction &CGF, const Expr *E, Address Base, llvm::Value *MemPtr, @@ -156,14 +152,14 @@ class ItaniumCXXABI : public CodeGen::CGCXXABI { llvm::Constant *BuildMemberPointer(const CXXMethodDecl *MD, CharUnits ThisAdjustment); - llvm::Value *EmitMemberPointerComparison(CodeGenFunction &CGF, - llvm::Value *L, llvm::Value *R, + llvm::Value *EmitMemberPointerComparison(CodeGenFunction &CGF, llvm::Value *L, + llvm::Value *R, const MemberPointerType *MPT, bool Inequality) override; - llvm::Value *EmitMemberPointerIsNotNull(CodeGenFunction &CGF, - llvm::Value *Addr, - const MemberPointerType *MPT) override; + llvm::Value * + EmitMemberPointerIsNotNull(CodeGenFunction &CGF, llvm::Value *Addr, + const MemberPointerType *MPT) override; void emitVirtualObjectDelete(CodeGenFunction &CGF, const CXXDeleteExpr *DE, Address Ptr, QualType ElementType, @@ -260,9 +256,9 @@ class ItaniumCXXABI : public CodeGen::CGCXXABI { bool EmitBadCastCall(CodeGenFunction &CGF) override; llvm::Value * - GetVirtualBaseClassOffset(CodeGenFunction &CGF, Address This, - const CXXRecordDecl *ClassDecl, - const CXXRecordDecl *BaseClassDecl) override; + GetVirtualBaseClassOffset(CodeGenFunction &CGF, Address This, + const CXXRecordDecl *ClassDecl, + const CXXRecordDecl *BaseClassDecl) override; void EmitCXXConstructors(const CXXConstructorDecl *D) override; @@ -368,17 +364,16 @@ class ItaniumCXXABI : public CodeGen::CGCXXABI { } StringRef GetPureVirtualCallName() override { return "__cxa_pure_virtual"; } - StringRef GetDeletedVirtualCallName() override - { return "__cxa_deleted_virtual"; } + StringRef GetDeletedVirtualCallName() override { + return "__cxa_deleted_virtual"; + } CharUnits getArrayCookieSizeImpl(QualType elementType) override; - Address InitializeArrayCookie(CodeGenFunction &CGF, - Address NewPtr, + Address InitializeArrayCookie(CodeGenFunction &CGF, Address NewPtr, llvm::Value *NumElements, const CXXNewExpr *expr, QualType ElementType) override; - llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF, - Address allocPtr, + llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF, Address allocPtr, CharUnits cookieSize) override; void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D, @@ -391,14 +386,12 @@ class ItaniumCXXABI : public CodeGen::CGCXXABI { llvm::Function *getOrCreateThreadLocalWrapper(const VarDecl *VD, llvm::Value *Val); void EmitThreadLocalInitFuncs( - CodeGenModule &CGM, - ArrayRef<const VarDecl *> CXXThreadLocals, + CodeGenModule &CGM, ArrayRef<const VarDecl *> CXXThreadLocals, ArrayRef<llvm::Function *> CXXThreadLocalInits, ArrayRef<const VarDecl *> CXXThreadLocalInitVars) override; bool usesThreadWrapperFunction(const VarDecl *VD) const override { - return !isEmittedWithConstantInitializer(VD) || - mayNeedDestruction(VD); + return !isEmittedWithConstantInitializer(VD) || mayNeedDestruction(VD); } LValue EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF, const VarDecl *VD, QualType LValType) override; @@ -445,43 +438,43 @@ class ItaniumCXXABI : public CodeGen::CGCXXABI { LoadVTablePtr(CodeGenFunction &CGF, Address This, const CXXRecordDecl *RD) override; - private: - llvm::Constant * - getSignedVirtualMemberFunctionPointer(const CXXMethodDecl *MD); - - bool hasAnyUnusedVirtualInlineFunction(const CXXRecordDecl *RD) const { - const auto &VtableLayout = - CGM.getItaniumVTableContext().getVTableLayout(RD); - - for (const auto &VtableComponent : VtableLayout.vtable_components()) { - // Skip empty slot. - if (!VtableComponent.isUsedFunctionPointerKind()) - continue; - - const CXXMethodDecl *Method = VtableComponent.getFunctionDecl(); - const FunctionDecl *FD = Method->getDefinition(); - const bool IsInlined = - Method->getCanonicalDecl()->isInlined() || (FD && FD->isInlined()); - if (!IsInlined) - continue; - - StringRef Name = CGM.getMangledName( - VtableComponent.getGlobalDecl(/*HasVectorDeletingDtors=*/false)); - 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 - // after trying to emit vtable speculatively. Because of this we do - // an extra pass after emitting all deferred vtables to find and emit - // these vtables opportunistically. - if (!Entry || Entry->isDeclaration()) - return true; - } - return false; +private: + llvm::Constant * + getSignedVirtualMemberFunctionPointer(const CXXMethodDecl *MD); + + bool hasAnyUnusedVirtualInlineFunction(const CXXRecordDecl *RD) const { + const auto &VtableLayout = + CGM.getItaniumVTableContext().getVTableLayout(RD); + + for (const auto &VtableComponent : VtableLayout.vtable_components()) { + // Skip empty slot. + if (!VtableComponent.isUsedFunctionPointerKind()) + continue; + + const CXXMethodDecl *Method = VtableComponent.getFunctionDecl(); + const FunctionDecl *FD = Method->getDefinition(); + const bool IsInlined = + Method->getCanonicalDecl()->isInlined() || (FD && FD->isInlined()); + if (!IsInlined) + continue; + + StringRef Name = CGM.getMangledName( + VtableComponent.getGlobalDecl(/*HasVectorDeletingDtors=*/false)); + 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 + // after trying to emit vtable speculatively. Because of this we do + // an extra pass after emitting all deferred vtables to find and emit + // these vtables opportunistically. + if (!Entry || Entry->isDeclaration()) + return true; + } + return false; } bool isVTableHidden(const CXXRecordDecl *RD) const { const auto &VtableLayout = - CGM.getItaniumVTableContext().getVTableLayout(RD); + CGM.getItaniumVTableContext().getVTableLayout(RD); for (const auto &VtableComponent : VtableLayout.vtable_components()) { if (VtableComponent.isRTTIKind()) { @@ -501,9 +494,9 @@ class ItaniumCXXABI : public CodeGen::CGCXXABI { class ARMCXXABI : public ItaniumCXXABI { public: - ARMCXXABI(CodeGen::CodeGenModule &CGM) : - ItaniumCXXABI(CGM, /*UseARMMethodPtrABI=*/true, - /*UseARMGuardVarABI=*/true) {} + ARMCXXABI(CodeGen::CodeGenModule &CGM) + : ItaniumCXXABI(CGM, /*UseARMMethodPtrABI=*/true, + /*UseARMGuardVarABI=*/true) {} bool constructorsAndDestructorsReturnThis() const override { return true; } @@ -511,8 +504,7 @@ class ARMCXXABI : public ItaniumCXXABI { QualType ResTy) override; CharUnits getArrayCookieSizeImpl(QualType elementType) override; - Address InitializeArrayCookie(CodeGenFunction &CGF, - Address NewPtr, + Address InitializeArrayCookie(CodeGenFunction &CGF, Address NewPtr, llvm::Value *NumElements, const CXXNewExpr *expr, QualType ElementType) override; @@ -532,8 +524,7 @@ class AppleARM64CXXABI : public ARMCXXABI { class FuchsiaCXXABI final : public ItaniumCXXABI { public: - explicit FuchsiaCXXABI(CodeGen::CodeGenModule &CGM) - : ItaniumCXXABI(CGM) {} + explicit FuchsiaCXXABI(CodeGen::CodeGenModule &CGM) : ItaniumCXXABI(CGM) {} private: bool constructorsAndDestructorsReturnThis() const override { return true; } @@ -556,8 +547,7 @@ class WebAssemblyCXXABI final : public ItaniumCXXABI { class XLCXXABI final : public ItaniumCXXABI { public: - explicit XLCXXABI(CodeGen::CodeGenModule &CGM) - : ItaniumCXXABI(CGM) {} + explicit XLCXXABI(CodeGen::CodeGenModule &CGM) : ItaniumCXXABI(CGM) {} void registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D, llvm::FunctionCallee dtor, @@ -569,7 +559,7 @@ class XLCXXABI final : public ItaniumCXXABI { void emitCXXStermFinalizer(const VarDecl &D, llvm::Function *dtorStub, llvm::Constant *addr); }; -} +} // namespace CodeGen::CGCXXABI *CodeGen::CreateItaniumCXXABI(CodeGenModule &CGM) { switch (CGM.getContext().getCXXABIKind()) { @@ -640,8 +630,8 @@ ItaniumCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) { /// the function to call. CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer( CodeGenFunction &CGF, const Expr *E, Address ThisAddr, - llvm::Value *&ThisPtrForCall, - llvm::Value *MemFnPtr, const MemberPointerType *MPT) { + llvm::Value *&ThisPtrForCall, llvm::Value *MemFnPtr, + const MemberPointerType *MPT) { CGBuilderTy &Builder = CGF.Builder; const FunctionProtoType *FPT = @@ -688,9 +678,8 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer( // Cast the adjusted this to a pointer to vtable pointer and load. llvm::Type *VTableTy = CGF.CGM.GlobalsInt8PtrTy; - CharUnits VTablePtrAlign = - CGF.CGM.getDynamicOffsetAlignment(ThisAddr.getAlignment(), RD, - CGF.getPointerAlign()); + CharUnits VTablePtrAlign = CGF.CGM.getDynamicOffsetAlignment( + ThisAddr.getAlignment(), RD, CGF.getPointerAlign()); llvm::Value *VTable = CGF.GetVTablePtr( Address(This, ThisAddr.getElementType(), VTablePtrAlign), VTableTy, RD); @@ -952,10 +941,9 @@ static llvm::Constant *pointerAuthResignConstant( /// MP when the derived MP does not point to a member of the base. /// This is why -1 is a reasonable choice for null data member /// pointers. -llvm::Value * -ItaniumCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF, - const CastExpr *E, - llvm::Value *src) { +llvm::Value *ItaniumCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF, + const CastExpr *E, + llvm::Value *src) { // Use constant emission if we can. if (isa<llvm::Constant>(src)) return EmitMemberPointerConversion(E, cast<llvm::Constant>(src)); @@ -1008,15 +996,16 @@ ItaniumCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF, } // Under Itanium, reinterprets don't require any additional processing. - if (E->getCastKind() == CK_ReinterpretMemberPointer) return src; + if (E->getCastKind() == CK_ReinterpretMemberPointer) + return src; llvm::Constant *adj = getMemberPointerAdjustment(E); - if (!adj) return src; + if (!adj) + return src; bool isDerivedToBase = (E->getCastKind() == CK_DerivedToBaseMemberPointer); - const MemberPointerType *destTy = - E->getType()->castAs<MemberPointerType>(); + const MemberPointerType *destTy = E->getType()->castAs<MemberPointerType>(); // For member data pointers, this is just a matter of adding the // offset if the source is non-null. @@ -1092,22 +1081,24 @@ ItaniumCXXABI::EmitMemberPointerConversion(const CastExpr *E, src, DstType, E->getSubExpr()->getType(), CGM); // Under Itanium, reinterprets don't require any additional processing. - if (E->getCastKind() == CK_ReinterpretMemberPointer) return src; + if (E->getCastKind() == CK_ReinterpretMemberPointer) + return src; // If the adjustment is trivial, we don't need to do anything. llvm::Constant *adj = getMemberPointerAdjustment(E); - if (!adj) return src; + if (!adj) + return src; bool isDerivedToBase = (E->getCastKind() == CK_DerivedToBaseMemberPointer); - const MemberPointerType *destTy = - E->getType()->castAs<MemberPointerType>(); + const MemberPointerType *destTy = E->getType()->castAs<MemberPointerType>(); // For member data pointers, this is just a matter of adding the // offset if the source is non-null. if (destTy->isMemberDataPointer()) { // null maps to null. - if (src->isAllOnesValue()) return src; + if (src->isAllOnesValue()) + return src; if (isDerivedToBase) return llvm::ConstantExpr::getNSWSub(src, adj); @@ -1142,7 +1133,7 @@ ItaniumCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) { return llvm::ConstantInt::get(CGM.PtrDiffTy, -1ULL, /*isSigned=*/true); llvm::Constant *Zero = llvm::ConstantInt::get(CGM.PtrDiffTy, 0); - llvm::Constant *Values[2] = { Zero, Zero }; + llvm::Constant *Values[2] = {Zero, Zero}; return llvm::ConstantStruct::getAnon(Values); } @@ -1220,8 +1211,8 @@ llvm::Constant *ItaniumCXXABI::BuildMemberPointer(const CXXMethodDecl *MD, // virtual table offset (in bytes) of the function, // represented as a ptrdiff_t. MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset + 1); - MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy, - ThisAdjustment.getQuantity()); + MemPtr[1] = + llvm::ConstantInt::get(CGM.PtrDiffTy, ThisAdjustment.getQuantity()); } } else { const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>(); @@ -1238,9 +1229,9 @@ llvm::Constant *ItaniumCXXABI::BuildMemberPointer(const CXXMethodDecl *MD, llvm::Constant *addr = CGM.getMemberFunctionPointer(MD, Ty); MemPtr[0] = llvm::ConstantExpr::getPtrToInt(addr, CGM.PtrDiffTy); - MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy, - (UseARMMethodPtrABI ? 2 : 1) * - ThisAdjustment.getQuantity()); + MemPtr[1] = + llvm::ConstantInt::get(CGM.PtrDiffTy, (UseARMMethodPtrABI ? 2 : 1) * + ThisAdjustment.getQuantity()); } return llvm::ConstantStruct::getAnon(MemPtr); @@ -1264,7 +1255,7 @@ llvm::Constant *ItaniumCXXABI::EmitMemberPointer(const APValue &MP, getContext().recordMemberDataPointerEvaluation(MPD); CharUnits FieldOffset = - getContext().toCharUnitsFromBits(getContext().getFieldOffset(MPD)); + getContext().toCharUnitsFromBits(getContext().getFieldOffset(MPD)); return EmitMemberDataPointer(MPT, ThisAdjustment + FieldOffset); } @@ -1272,12 +1263,9 @@ llvm::Constant *ItaniumCXXABI::EmitMemberPointer(const APValue &MP, /// the same if they're either bitwise identical *or* both null. /// /// ARM is different here only because null-ness is more complicated. -llvm::Value * -ItaniumCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF, - llvm::Value *L, - llvm::Value *R, - const MemberPointerType *MPT, - bool Inequality) { +llvm::Value *ItaniumCXXABI::EmitMemberPointerComparison( + CodeGenFunction &CGF, llvm::Value *L, llvm::Value *R, + const MemberPointerType *MPT, bool Inequality) { CGBuilderTy &Builder = CGF.Builder; llvm::ICmpInst::Predicate Eq; @@ -1334,8 +1322,8 @@ ItaniumCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF, // Compute (l.adj | r.adj) & 1 and test it against zero. llvm::Value *OrAdj = Builder.CreateOr(LAdj, RAdj, "or.adj"); llvm::Value *OrAdjAnd1 = Builder.CreateAnd(OrAdj, One); - llvm::Value *OrAdjAnd1EqZero = Builder.CreateICmp(Eq, OrAdjAnd1, Zero, - "cmp.or.adj"); + llvm::Value *OrAdjAnd1EqZero = + Builder.CreateICmp(Eq, OrAdjAnd1, Zero, "cmp.or.adj"); EqZero = Builder.CreateBinOp(And, EqZero, OrAdjAnd1EqZero); } @@ -1346,17 +1334,15 @@ ItaniumCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF, return Result; } -llvm::Value * -ItaniumCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF, - llvm::Value *MemPtr, - const MemberPointerType *MPT) { +llvm::Value *ItaniumCXXABI::EmitMemberPointerIsNotNull( + CodeGenFunction &CGF, llvm::Value *MemPtr, const MemberPointerType *MPT) { CGBuilderTy &Builder = CGF.Builder; /// For member data pointers, this is just a check against -1. if (MPT->isMemberDataPointer()) { assert(MemPtr->getType() == CGM.PtrDiffTy); llvm::Value *NegativeOne = - llvm::Constant::getAllOnesValue(MemPtr->getType()); + llvm::Constant::getAllOnesValue(MemPtr->getType()); return Builder.CreateICmpNE(MemPtr, NegativeOne, "memptr.tobool"); } @@ -1372,8 +1358,8 @@ ItaniumCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF, llvm::Constant *One = llvm::ConstantInt::get(Ptr->getType(), 1); llvm::Value *Adj = Builder.CreateExtractValue(MemPtr, 1, "memptr.adj"); llvm::Value *VirtualBit = Builder.CreateAnd(Adj, One, "memptr.virtualbit"); - llvm::Value *IsVirtual = Builder.CreateICmpNE(VirtualBit, Zero, - "memptr.isvirtual"); + llvm::Value *IsVirtual = + Builder.CreateICmpNE(VirtualBit, Zero, "memptr.isvirtual"); Result = Builder.CreateOr(Result, IsVirtual); } @@ -1408,8 +1394,7 @@ bool ItaniumCXXABI::isZeroInitializable(const MemberPointerType *MPT) { /// at entry -2 in the vtable. void ItaniumCXXABI::emitVirtualObjectDelete(CodeGenFunction &CGF, const CXXDeleteExpr *DE, - Address Ptr, - QualType ElementType, + Address Ptr, QualType ElementType, const CXXDestructorDecl *Dtor) { bool UseGlobalDelete = DE->isGlobalDelete(); if (UseGlob... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/216611 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
