From: Eli Friedman Date: Thu, 1 Dec 2011 00:37:01 +0000 (+0000) Subject: Fix MSVC class layout for empty classes. Patch by Dmitry Sokolov. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=901dd668931a70932ad09092959c42693409a3cd;p=clang Fix MSVC class layout for empty classes. Patch by Dmitry Sokolov. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@145544 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp index 60a7c2d1fe..88a90a4172 100644 --- a/lib/AST/RecordLayoutBuilder.cpp +++ b/lib/AST/RecordLayoutBuilder.cpp @@ -1399,10 +1399,8 @@ void RecordLayoutBuilder::Layout(const CXXRecordDecl *RD) { } // Finally, round the size of the total struct up to the alignment - // of the struct itself. Amazingly, this does not occur in the MS - // ABI after virtual base layout. - if (!isMicrosoftCXXABI() || RD->getNumVBases()) - FinishLayout(RD); + // of the struct itself. + FinishLayout(RD); #ifndef NDEBUG // Check that we have base offsets for all bases. @@ -1882,6 +1880,13 @@ void RecordLayoutBuilder::FinishLayout(const NamedDecl *D) { else setSize(CharUnits::One()); } + + // MSVC doesn't round up to the alignment of the record with virtual bases. + if (const CXXRecordDecl *RD = dyn_cast(D)) { + if (isMicrosoftCXXABI() && RD->getNumVBases()) + return; + } + // Finally, round the size of the record up to the alignment of the // record itself. uint64_t UnpaddedSize = getSizeInBits() - UnfilledBitsInLastByte; diff --git a/test/Sema/ms_class_layout.cpp b/test/Sema/ms_class_layout.cpp index 66d711fb43..ea3f899ea2 100644 --- a/test/Sema/ms_class_layout.cpp +++ b/test/Sema/ms_class_layout.cpp @@ -95,6 +95,7 @@ struct P : public M, public virtual L { int p; }; +struct R {}; #pragma pack(pop) @@ -111,6 +112,7 @@ int main() { N* n; O* o; P* p; + R* r; return 0; } @@ -325,3 +327,9 @@ int main() { // CHECK-NEXT: nvsize=12, nvalign=4 //CHECK: %struct.P = type { %struct.M.base, i32, %struct.K, %struct.L } + +// CHECK: 0 | struct R (empty) +// CHECK-NEXT: sizeof=1, dsize=0, align=1 +// CHECK-NEXT: nvsize=0, nvalign=1 + +//CHECK: %struct.R = type { i8 }