Skip to content

Commit 83a1258

Browse files
committed
Fix MSVC class layout for empty classes. Patch by Dmitry Sokolov.
llvm-svn: 145544
1 parent dc82cca commit 83a1258

File tree

2 files changed

+17
-4
lines changed

2 files changed

+17
-4
lines changed

clang/lib/AST/RecordLayoutBuilder.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1399,10 +1399,8 @@ void RecordLayoutBuilder::Layout(const CXXRecordDecl *RD) {
13991399
}
14001400

14011401
// Finally, round the size of the total struct up to the alignment
1402-
// of the struct itself. Amazingly, this does not occur in the MS
1403-
// ABI after virtual base layout.
1404-
if (!isMicrosoftCXXABI() || RD->getNumVBases())
1405-
FinishLayout(RD);
1402+
// of the struct itself.
1403+
FinishLayout(RD);
14061404

14071405
#ifndef NDEBUG
14081406
// Check that we have base offsets for all bases.
@@ -1882,6 +1880,13 @@ void RecordLayoutBuilder::FinishLayout(const NamedDecl *D) {
18821880
else
18831881
setSize(CharUnits::One());
18841882
}
1883+
1884+
// MSVC doesn't round up to the alignment of the record with virtual bases.
1885+
if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
1886+
if (isMicrosoftCXXABI() && RD->getNumVBases())
1887+
return;
1888+
}
1889+
18851890
// Finally, round the size of the record up to the alignment of the
18861891
// record itself.
18871892
uint64_t UnpaddedSize = getSizeInBits() - UnfilledBitsInLastByte;

clang/test/Sema/ms_class_layout.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ struct P : public M, public virtual L {
9595
int p;
9696
};
9797

98+
struct R {};
9899

99100
#pragma pack(pop)
100101

@@ -111,6 +112,7 @@ int main() {
111112
N* n;
112113
O* o;
113114
P* p;
115+
R* r;
114116
return 0;
115117
}
116118

@@ -325,3 +327,9 @@ int main() {
325327
// CHECK-NEXT: nvsize=12, nvalign=4
326328

327329
//CHECK: %struct.P = type { %struct.M.base, i32, %struct.K, %struct.L }
330+
331+
// CHECK: 0 | struct R (empty)
332+
// CHECK-NEXT: sizeof=1, dsize=0, align=1
333+
// CHECK-NEXT: nvsize=0, nvalign=1
334+
335+
//CHECK: %struct.R = type { i8 }

0 commit comments

Comments
 (0)