aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/AST/RecordLayoutBuilder.cpp6
-rw-r--r--test/CodeGenCXX/vtable-layout.cpp23
2 files changed, 28 insertions, 1 deletions
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() { }
+
+}