diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp index b2426833a2..2bc2a128f4 100644 --- a/lib/AST/RecordLayoutBuilder.cpp +++ b/lib/AST/RecordLayoutBuilder.cpp @@ -263,8 +263,12 @@ ASTRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *RD, uint64_t BaseOffset; if (I->isVirtual()) { + // If we don't know this vbase yet, don't visit it. It will be visited + // later. + if (!VBases.count(Base)) + continue; + // We want the vbase offset from the class we're currently laying out. - assert(VBases.count(Base) && "Did not find virtual base!"); BaseOffset = VBases[Base]; } else if (RD == MostDerivedClass) { // We want the base offset from the class we're currently laying out. diff --git a/test/CodeGenCXX/vtable-layout.cpp b/test/CodeGenCXX/vtable-layout.cpp index 62e02fcea5..243d373d3a 100644 --- a/test/CodeGenCXX/vtable-layout.cpp +++ b/test/CodeGenCXX/vtable-layout.cpp @@ -1364,3 +1364,26 @@ struct D : virtual C { void D::f() { } } + +namespace Test32 { + +// Check that we correctly lay out the virtual bases of 'Test32::D'. + +struct A { + virtual void f(); +}; + +struct B : virtual A { }; +struct C : A, virtual B { }; +struct D : virtual B { }; + +// CHECK: Virtual base offset offsets for 'Test32::E' (3 entries). +// CHECK-NEXT: Test32::A | -32 +// CHECK-NEXT: Test32::B | -24 +// CHECK-NEXT: Test32::D | -40 +struct E : C, virtual D { + virtual void f(); +}; +void E::f() { } + +}