diff options
| -rw-r--r-- | clang/lib/AST/RecordLayoutBuilder.cpp | 13 | ||||
| -rw-r--r-- | clang/test/Sema/ms_class_layout.cpp | 8 |
2 files changed, 17 insertions, 4 deletions
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp index 60a7c2d1fe7..88a90a41729 100644 --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/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<CXXRecordDecl>(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/clang/test/Sema/ms_class_layout.cpp b/clang/test/Sema/ms_class_layout.cpp index 66d711fb430..ea3f899ea24 100644 --- a/clang/test/Sema/ms_class_layout.cpp +++ b/clang/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 } |

