r279786 - Widen type of __offset_flags in RTTI on Mingw64

Reid Kleckner via cfe-commits cfe-commits at lists.llvm.org
Thu Aug 25 15:16:31 PDT 2016


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




More information about the cfe-commits mailing list