From d8b0466e19df2be3d635ca4e23c92c3d28d1b935 Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Thu, 25 Aug 2016 22:16:30 +0000 Subject: Widen type of __offset_flags in RTTI on Mingw64 Otherwise we can't handle secondary base classes at offsets greater than 2**24. This agrees with libstdc++abi. We could extend this change to other LLP64 platforms, but then we would want to update libc++abi and it would require additional review. Fixes PR29116 llvm-svn: 279786 --- clang/lib/CodeGen/ItaniumCXXABI.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'clang/lib') diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index 2492c82f862..ecf4d0411f5 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -3217,9 +3217,6 @@ void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(const CXXRecordDecl *RD) { if (!RD->getNumBases()) return; - llvm::Type *LongLTy = - CGM.getTypes().ConvertType(CGM.getContext().LongTy); - // Now add the base class descriptions. // Itanium C++ ABI 2.9.5p6c: @@ -3237,6 +3234,19 @@ void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(const CXXRecordDecl *RD) { // __offset_shift = 8 // }; // }; + + // If we're in mingw and 'long' isn't wide enough for a pointer, use 'long + // long' instead of 'long' for __offset_flags. libstdc++abi uses long long on + // LLP64 platforms. + // FIXME: Consider updating libc++abi to match, and extend this logic to all + // LLP64 platforms. + QualType OffsetFlagsTy = CGM.getContext().LongTy; + const TargetInfo &TI = CGM.getContext().getTargetInfo(); + if (TI.getTriple().isOSCygMing() && TI.getPointerWidth(0) > TI.getLongWidth()) + OffsetFlagsTy = CGM.getContext().LongLongTy; + llvm::Type *OffsetFlagsLTy = + CGM.getTypes().ConvertType(OffsetFlagsTy); + for (const auto &Base : RD->bases()) { // The __base_type member points to the RTTI for the base type. Fields.push_back(ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(Base.getType())); @@ -3268,7 +3278,7 @@ void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(const CXXRecordDecl *RD) { if (Base.getAccessSpecifier() == AS_public) OffsetFlags |= BCTI_Public; - Fields.push_back(llvm::ConstantInt::get(LongLTy, OffsetFlags)); + Fields.push_back(llvm::ConstantInt::get(OffsetFlagsLTy, OffsetFlags)); } } -- cgit v1.2.3