diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp index 885d4ff5fb6738a524c5b553762f51505d8070ed..e9289a0f055dcac953b1a9d2f888ee436951c5ea 100644 --- a/lib/AST/RecordLayoutBuilder.cpp +++ b/lib/AST/RecordLayoutBuilder.cpp @@ -2302,8 +2302,10 @@ MicrosoftRecordLayoutBuilder::layoutNonVirtualBases(const CXXRecordDecl *RD) { if (!BaseLayout.hasExtendableVFPtr()) continue; // If we don't have a primary base, this one qualifies. - if (!PrimaryBase) + if (!PrimaryBase) { PrimaryBase = BaseDecl; + LeadsWithZeroSizedBase = BaseLayout.leadsWithZeroSizedBase(); + } // Lay out the base. layoutNonVirtualBase(BaseDecl, BaseLayout, PreviousBaseLayout); } diff --git a/test/Layout/ms-x86-alias-avoidance-padding.cpp b/test/Layout/ms-x86-alias-avoidance-padding.cpp index 48249137017969f8c85af35221bc397c960bb29e..3112b39c9bc677c230171040893e535e789fee7a 100644 --- a/test/Layout/ms-x86-alias-avoidance-padding.cpp +++ b/test/Layout/ms-x86-alias-avoidance-padding.cpp @@ -255,10 +255,54 @@ struct F : virtual D, virtual B {}; // CHECK-X64-NEXT: | [sizeof=32, align=8 // CHECK-X64-NEXT: | nvsize=8, nvalign=8] +struct JC0 { + JC0() { printf("JC0 : %d\n", (int)((char*)this - buffer)); } +}; +struct JC1 : JC0 { + virtual void f() {} + JC1() { printf("JC1 : %d\n", (int)((char*)this - buffer)); } +}; +struct JC2 : JC1 { + JC2() { printf("JC2 : %d\n", (int)((char*)this - buffer)); } +}; +struct JC4 : JC1, JC2 { + JC4() { printf("JC4 : %d\n", (int)((char*)this - buffer)); } +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK: *** Dumping AST Record Layout +// CHECK: *** Dumping AST Record Layout +// CHECK: *** Dumping AST Record Layout +// CHECK-NEXT: 0 | struct JC4 +// CHECK-NEXT: 0 | struct JC1 (primary base) +// CHECK-NEXT: 0 | (JC1 vftable pointer) +// CHECK-NEXT: 4 | struct JC0 (base) (empty) +// CHECK-NEXT: 8 | struct JC2 (base) +// CHECK-NEXT: 8 | struct JC1 (primary base) +// CHECK-NEXT: 8 | (JC1 vftable pointer) +// CHECK-NEXT: 12 | struct JC0 (base) (empty) +// CHECK-NEXT: | [sizeof=12, align=4 +// CHECK-NEXT: | nvsize=12, nvalign=4] +// CHECK-x64: *** Dumping AST Record Layout +// CHECK-x64: *** Dumping AST Record Layout +// CHECK-x64: *** Dumping AST Record Layout +// CHECK-x64: *** Dumping AST Record Layout +// CHECK-x64-NEXT: 0 | struct JC4 +// CHECK-x64-NEXT: 0 | struct JC1 (primary base) +// CHECK-x64-NEXT: 0 | (JC1 vftable pointer) +// CHECK-x64-NEXT: 8 | struct JC0 (base) (empty) +// CHECK-x64-NEXT: 16 | struct JC2 (base) +// CHECK-x64-NEXT: 16 | struct JC1 (primary base) +// CHECK-x64-NEXT: 16 | (JC1 vftable pointer) +// CHECK-x64-NEXT: 24 | struct JC0 (base) (empty) +// CHECK-x64-NEXT: | [sizeof=24, align=8 +// CHECK-x64-NEXT: | nvsize=24, nvalign=8] + int a[ sizeof(AT3) + sizeof(BT3) + sizeof(T3) + sizeof(E) + sizeof(F) + +sizeof(JC4) + 0];