diff options
-rw-r--r-- | lib/AST/RecordLayoutBuilder.cpp | 7 | ||||
-rw-r--r-- | test/SemaCXX/empty-class-layout.cpp | 18 |
2 files changed, 25 insertions, 0 deletions
diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp index 30db457728..6b635aef4e 100644 --- a/lib/AST/RecordLayoutBuilder.cpp +++ b/lib/AST/RecordLayoutBuilder.cpp @@ -530,8 +530,15 @@ void ASTRecordLayoutBuilder::UpdateEmptyClassOffsets(const CXXRecordDecl *RD, UpdateEmptyClassOffsets(FD, Offset + FieldOffset); } + const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); + if (UpdateVBases) { // FIXME: Update virtual bases. + } else if (PrimaryBase && Layout.getPrimaryBaseWasVirtual()) { + // We always want to update the offsets of a primary virtual base. + assert(Layout.getVBaseClassOffset(PrimaryBase) == 0 && + "primary base class offset must always be 0!"); + UpdateEmptyClassOffsets(PrimaryBase, Offset, /*UpdateVBases=*/false); } } diff --git a/test/SemaCXX/empty-class-layout.cpp b/test/SemaCXX/empty-class-layout.cpp index c3dc7330fe..27f5040e18 100644 --- a/test/SemaCXX/empty-class-layout.cpp +++ b/test/SemaCXX/empty-class-layout.cpp @@ -2,6 +2,8 @@ #define SA(n, p) int a##n[(p) ? 1 : -1] +namespace Test0 { + struct A { int a; }; SA(0, sizeof(A) == 4); @@ -66,3 +68,19 @@ SA(11, sizeof(S7) == 8); struct S8 : Empty, A { }; SA(12, sizeof(S8) == 4); + +} + +namespace Test1 { + +// Test that we don't try to place both A subobjects at offset 0. +struct A { }; +class B { virtual void f(); }; +class C : A, virtual B { }; +struct D : virtual C { }; +struct E : virtual A { }; +class F : D, E { }; + +SA(0, sizeof(F) == 24); + +} |