Author: rnk Date: Thu Aug 25 17:16:30 2016 New Revision: 279786 URL: http://llvm.org/viewvc/llvm-project?rev=279786&view=rev Log: 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 Added: cfe/trunk/test/CodeGenCXX/rtti-mingw64.cpp Modified: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp Modified: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp?rev=279786&r1=279785&r2=279786&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp (original) +++ cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp Thu Aug 25 17:16:30 2016 @@ -3217,9 +3217,6 @@ void ItaniumRTTIBuilder::BuildVMIClassTy 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::BuildVMIClassTy // __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::BuildVMIClassTy if (Base.getAccessSpecifier() == AS_public) OffsetFlags |= BCTI_Public; - Fields.push_back(llvm::ConstantInt::get(LongLTy, OffsetFlags)); + Fields.push_back(llvm::ConstantInt::get(OffsetFlagsLTy, OffsetFlags)); } } Added: cfe/trunk/test/CodeGenCXX/rtti-mingw64.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/rtti-mingw64.cpp?rev=279786&view=auto ============================================================================== --- cfe/trunk/test/CodeGenCXX/rtti-mingw64.cpp (added) +++ cfe/trunk/test/CodeGenCXX/rtti-mingw64.cpp Thu Aug 25 17:16:30 2016 @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -triple x86_64-windows-gnu %s -emit-llvm -o - | FileCheck %s +struct A { int a; }; +struct B : virtual A { int b; }; +B b; + +// CHECK: @_ZTI1B = linkonce_odr constant { i8*, i8*, i32, i32, i8*, i64 } +// CHECK-SAME: i8* bitcast (i8** getelementptr inbounds (i8*, i8** @_ZTVN10__cxxabiv121__vmi_class_type_infoE, i64 2) to i8*), +// CHECK-SAME: i8* getelementptr inbounds ([3 x i8], [3 x i8]* @_ZTS1B, i32 0, i32 0), +// CHECK-SAME: i32 0, +// CHECK-SAME: i32 1, +// CHECK-SAME: i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*), +// This i64 is important, it should be an i64, not an i32. +// CHECK-SAME: i64 -6141 }, comdat _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits