From d23b27e0d88e1218611721f5949f18559461afc4 Mon Sep 17 00:00:00 2001 From: John McCall Date: Fri, 16 Sep 2016 02:40:45 +0000 Subject: Alter the iOS/tvOS ARM64 C++ ABI to ignore the upper half of the virtual table offset in a member function pointer. We are reserving this space for future ABI use relating to alternative v-table configurations. In the meantime, continue to zero-initialize this space when actually emitting a member pointer literal. This will successfully interoperate with existing compilers. Future versions of the compiler may place additional data in this location, and at that point, code emitted by compilers prior to this patch will fail if exposed to such a member pointer. This is therefore a somewhat hard ABI break. However, because it is limited to an uncommon case of an uncommon language feature, and especially because interoperation with the standard library does not depend on member pointers, we believe that with a sufficiently advance compiler change the impact of this break will be minimal in practice. llvm-svn: 281693 --- clang/lib/CodeGen/ItaniumCXXABI.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'clang/lib/CodeGen') diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index bd9e882dac4..08c86176abc 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -45,6 +45,7 @@ class ItaniumCXXABI : public CodeGen::CGCXXABI { protected: bool UseARMMethodPtrABI; bool UseARMGuardVarABI; + bool Use32BitVTableOffsetABI; ItaniumMangleContext &getMangleContext() { return cast(CodeGen::CGCXXABI::getMangleContext()); @@ -55,7 +56,8 @@ public: bool UseARMMethodPtrABI = false, bool UseARMGuardVarABI = false) : CGCXXABI(CGM), UseARMMethodPtrABI(UseARMMethodPtrABI), - UseARMGuardVarABI(UseARMGuardVarABI) { } + UseARMGuardVarABI(UseARMGuardVarABI), + Use32BitVTableOffsetABI(false) { } bool classifyReturnType(CGFunctionInfo &FI) const override; @@ -425,7 +427,9 @@ public: class iOS64CXXABI : public ARMCXXABI { public: - iOS64CXXABI(CodeGen::CodeGenModule &CGM) : ARMCXXABI(CGM) {} + iOS64CXXABI(CodeGen::CodeGenModule &CGM) : ARMCXXABI(CGM) { + Use32BitVTableOffsetABI = true; + } // ARM64 libraries are prepared for non-unique RTTI. bool shouldRTTIBeUnique() const override { return false; } @@ -579,9 +583,15 @@ llvm::Value *ItaniumCXXABI::EmitLoadOfMemberFunctionPointer( CGF.GetVTablePtr(Address(This, VTablePtrAlign), VTableTy, RD); // Apply the offset. + // On ARM64, to reserve extra space in virtual member function pointers, + // we only pay attention to the low 32 bits of the offset. llvm::Value *VTableOffset = FnAsInt; if (!UseARMMethodPtrABI) VTableOffset = Builder.CreateSub(VTableOffset, ptrdiff_1); + if (Use32BitVTableOffsetABI) { + VTableOffset = Builder.CreateTrunc(VTableOffset, CGF.Int32Ty); + VTableOffset = Builder.CreateZExt(VTableOffset, CGM.PtrDiffTy); + } VTable = Builder.CreateGEP(VTable, VTableOffset); // Load the virtual function to call. -- cgit v1.2.3