summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/RecordLayoutBuilder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST/RecordLayoutBuilder.cpp')
-rw-r--r--clang/lib/AST/RecordLayoutBuilder.cpp9
1 files changed, 9 insertions, 0 deletions
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp
index 87d00bc9f5d..08c9da35873 100644
--- a/clang/lib/AST/RecordLayoutBuilder.cpp
+++ b/clang/lib/AST/RecordLayoutBuilder.cpp
@@ -2014,6 +2014,10 @@ static bool isMsLayout(const RecordDecl* D) {
// one.
// * The last zero size virtual base may be placed at the end of the struct.
// and can potentially alias a zero sized type in the next struct.
+// * If the last field is a non-zero length bitfield and we have any virtual
+// bases then some extra padding is added before the virtual bases for no
+// obvious reason.
+
namespace {
struct MicrosoftRecordLayoutBuilder {
@@ -2499,6 +2503,11 @@ void MicrosoftRecordLayoutBuilder::layoutVirtualBases(const CXXRecordDecl *RD) {
llvm::SmallPtrSet<const CXXRecordDecl *, 2> HasVtordisp =
computeVtorDispSet(RD);
+ // If the last field we laid out was a non-zero length bitfield then add some
+ // extra padding for no obvious reason.
+ if (LastFieldIsNonZeroWidthBitfield)
+ Size += CurrentBitfieldSize;
+
// Iterate through the virtual bases and lay them out.
for (CXXRecordDecl::base_class_const_iterator i = RD->vbases_begin(),
e = RD->vbases_end();
OpenPOWER on IntegriCloud