]> granicus.if.org Git - clang/commitdiff
Fix PR19066 - 0-sized vftable in the presence of virtual inheritance
authorTimur Iskhodzhanov <timurrrr@google.com>
Wed, 26 Mar 2014 08:12:53 +0000 (08:12 +0000)
committerTimur Iskhodzhanov <timurrrr@google.com>
Wed, 26 Mar 2014 08:12:53 +0000 (08:12 +0000)
Reviewed at http://llvm-reviews.chandlerc.com/D3181

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@204786 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/VTableBuilder.cpp
test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp

index eef91f7416e357c7bf7802c687347daf063e2b07..2d1e1a24089a85b6153b7a37e76768389c971467 100644 (file)
@@ -2531,6 +2531,7 @@ private:
     BasesSetVectorTy VisitedBases;
     AddMethods(BaseSubobject(MostDerivedClass, CharUnits::Zero()), 0, 0,
                VisitedBases);
+    assert(Components.size() && "vftable can't be empty");
 
     assert(MethodVFTableLocations.empty());
     for (MethodInfoMapTy::const_iterator I = MethodInfoMap.begin(),
@@ -2793,6 +2794,14 @@ bool VFTableBuilder::NeedsReturnAdjustingThunk(const CXXMethodDecl *MD) {
   return false;
 }
 
+static bool isDirectVBase(const CXXRecordDecl *Base, const CXXRecordDecl *RD) {
+  for (const auto &B : RD->bases()) {
+    if (B.isVirtual() && B.getType()->getAsCXXRecordDecl() == Base)
+      return true;
+  }
+  return false;
+}
+
 void VFTableBuilder::AddMethods(BaseSubobject Base, unsigned BaseDepth,
                                 const CXXRecordDecl *LastVBase,
                                 BasesSetVectorTy &VisitedBases) {
@@ -2808,7 +2817,7 @@ void VFTableBuilder::AddMethods(BaseSubobject Base, unsigned BaseDepth,
   CharUnits NextBaseOffset;
   if (BaseDepth < WhichVFPtr.PathToBaseWithVPtr.size()) {
     NextBase = WhichVFPtr.PathToBaseWithVPtr[BaseDepth];
-    if (Layout.getVBaseOffsetsMap().count(NextBase)) {
+    if (isDirectVBase(NextBase, RD)) {
       NextLastVBase = NextBase;
       NextBaseOffset = MostDerivedClassLayout.getVBaseClassOffset(NextBase);
     } else {
index 634f583e7358d73912b07b3d6ba7151ae4ce2552..1947b59715e6a599bda9beb01c993fb948a4fc72 100644 (file)
@@ -660,6 +660,21 @@ C c;
 // MANGLING-DAG: @"\01??_7C@pr17748@@6BB@1@@"
 }
 
+namespace pr19066 {
+struct X : virtual B {};
+
+struct Y : virtual X, B {
+  Y();
+  // CHECK-LABEL: VFTable for 'B' in 'pr19066::X' in 'pr19066::Y' (1 entry).
+  // CHECK-NEXT:  0 | void B::g()
+
+  // CHECK-LABEL: VFTable for 'B' in 'pr19066::Y' (1 entry).
+  // CHECK-NEXT:  0 | void B::g()
+};
+
+Y::Y() {}
+}
+
 namespace pr19240 {
 struct A {
   virtual void c();