r215285 - Fix PR20479 -- missing vftable slots in case of virtual inheritance vs return adjusting thunks

Timur Iskhodzhanov timurrrr at google.com
Sat Aug 9 10:08:06 PDT 2014


Author: timurrrr
Date: Sat Aug  9 12:08:06 2014
New Revision: 215285

URL: http://llvm.org/viewvc/llvm-project?rev=215285&view=rev
Log:
Fix PR20479 -- missing vftable slots in case of virtual inheritance vs return adjusting thunks

Reviewed at http://reviews.llvm.org/D4829

Modified:
    cfe/trunk/lib/AST/VTableBuilder.cpp
    cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp
    cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp

Modified: cfe/trunk/lib/AST/VTableBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/VTableBuilder.cpp?rev=215285&r1=215284&r2=215285&view=diff
==============================================================================
--- cfe/trunk/lib/AST/VTableBuilder.cpp (original)
+++ cfe/trunk/lib/AST/VTableBuilder.cpp Sat Aug  9 12:08:06 2014
@@ -3174,9 +3174,16 @@ void MicrosoftVTableContext::computeVTab
     Paths.push_back(new VPtrInfo(RD));
 
   // Recursive case: get all the vbtables from our bases and remove anything
-  // that shares a virtual base.
+  // that shares a virtual base.  Look at non-virtual bases first so we get
+  // longer inheritance paths from the derived class to the virtual bases.
+  llvm::SmallVector<CXXBaseSpecifier, 10> Bases;
+  std::copy_if(RD->bases_begin(), RD->bases_end(), std::back_inserter(Bases),
+               [](CXXBaseSpecifier bs) { return !bs.isVirtual(); });
+  std::copy_if(RD->bases_begin(), RD->bases_end(), std::back_inserter(Bases),
+               [](CXXBaseSpecifier bs) { return bs.isVirtual(); });
+
   llvm::SmallPtrSet<const CXXRecordDecl*, 4> VBasesSeen;
-  for (const auto &B : RD->bases()) {
+  for (const auto &B : Bases) {
     const CXXRecordDecl *Base = B.getType()->getAsCXXRecordDecl();
     if (B.isVirtual() && VBasesSeen.count(Base))
       continue;

Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp?rev=215285&r1=215284&r2=215285&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp Sat Aug  9 12:08:06 2014
@@ -104,3 +104,27 @@ K::K() {}
 // GLOBALS-LABEL: @"\01??_7K at test2@@6B@" = linkonce_odr unnamed_addr constant [3 x i8*]
 
 }
+
+namespace pr20479 {
+struct A {
+  virtual A *f();
+};
+
+struct B : virtual A {
+  virtual B *f();
+};
+
+struct C : virtual A, B {
+// VFTABLES-LABEL: VFTable for 'pr20479::A' in 'pr20479::B' in 'pr20479::C' (2 entries).
+// VFTABLES-NEXT:   0 | pr20479::B *pr20479::B::f()
+// VFTABLES-NEXT:       [return adjustment (to type 'struct pr20479::A *'): vbase #1, 0 non-virtual]
+// VFTABLES-NEXT:   1 | pr20479::B *pr20479::B::f()
+  C();
+};
+
+C::C() {}
+
+// GLOBALS-LABEL: @"\01??_7C at pr20479@@6B@" = linkonce_odr unnamed_addr constant [2 x i8*]
+// GLOBALS: @"\01?f at B@pr20479@@QAEPAUA at 2@XZ"
+// GLOBALS: @"\01?f at B@pr20479@@UAEPAU12 at XZ"
+}

Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp?rev=215285&r1=215284&r2=215285&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp Sat Aug  9 12:08:06 2014
@@ -573,6 +573,10 @@ struct Q {
 
 // PR19172: Yet another diamond we miscompiled.
 struct R : virtual Q, X {
+  // CHECK-LABEL: VFTable for 'vdtors::X' in 'vdtors::R' (2 entries).
+  // CHECK-NEXT: 0 | vdtors::R::~R() [scalar deleting]
+  // CHECK-NEXT: 1 | void vdtors::X::zzz()
+
   // CHECK-LABEL: VFTable for 'vdtors::Q' in 'vdtors::R' (1 entry).
   // CHECK-NEXT: 0 | vdtors::R::~R() [scalar deleting]
   // CHECK-NEXT:     [this adjustment: -8 non-virtual]
@@ -580,10 +584,6 @@ struct R : virtual Q, X {
   // CHECK-LABEL: Thunks for 'vdtors::R::~R()' (1 entry).
   // CHECK-NEXT: 0 | [this adjustment: -8 non-virtual]
 
-  // CHECK-LABEL: VFTable for 'vdtors::X' in 'vdtors::R' (2 entries).
-  // CHECK-NEXT: 0 | vdtors::R::~R() [scalar deleting]
-  // CHECK-NEXT: 1 | void vdtors::X::zzz()
-
   // CHECK-LABEL: VFTable indices for 'vdtors::R' (1 entry).
   // CHECK-NEXT: 0 | vdtors::R::~R() [scalar deleting]
   virtual ~R();
@@ -694,10 +694,10 @@ struct X : virtual B {};
 
 struct Y : virtual X, B {
   Y();
-  // CHECK-LABEL: VFTable for 'B' in 'pr19066::X' in 'pr19066::Y' (1 entry).
+  // CHECK-LABEL: VFTable for 'B' in 'pr19066::Y' (1 entry).
   // CHECK-NEXT:  0 | void B::g()
 
-  // CHECK-LABEL: VFTable for 'B' in 'pr19066::Y' (1 entry).
+  // CHECK-LABEL: VFTable for 'B' in 'pr19066::X' in 'pr19066::Y' (1 entry).
   // CHECK-NEXT:  0 | void B::g()
 };
 





More information about the cfe-commits mailing list