summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/AST/RecordLayoutBuilder.cpp8
-rw-r--r--clang/test/Sema/ms_bitfield_layout.c26
2 files changed, 29 insertions, 5 deletions
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp
index 04a0fab737a..5eb87e7fc75 100644
--- a/clang/lib/AST/RecordLayoutBuilder.cpp
+++ b/clang/lib/AST/RecordLayoutBuilder.cpp
@@ -2291,9 +2291,6 @@ MicrosoftRecordLayoutBuilder::getAdjustedElementInfo(
if (FD->hasAttr<PackedAttr>())
Info.Alignment = CharUnits::One();
Info.Alignment = std::max(Info.Alignment, FieldRequiredAlignment);
- // TODO: Add a Sema warning that MS ignores bitfield alignment in unions.
- if (!(FD->isBitField() && IsUnion))
- Alignment = std::max(Alignment, Info.Alignment);
return Info;
}
@@ -2472,6 +2469,7 @@ void MicrosoftRecordLayoutBuilder::layoutField(const FieldDecl *FD) {
}
LastFieldIsNonZeroWidthBitfield = false;
ElementInfo Info = getAdjustedElementInfo(FD);
+ Alignment = std::max(Alignment, Info.Alignment);
if (IsUnion) {
placeFieldAtOffset(CharUnits::Zero());
Size = std::max(Size, Info.Size);
@@ -2507,11 +2505,13 @@ void MicrosoftRecordLayoutBuilder::layoutBitField(const FieldDecl *FD) {
if (IsUnion) {
placeFieldAtOffset(CharUnits::Zero());
Size = std::max(Size, Info.Size);
+ // TODO: Add a Sema warning that MS ignores bitfield alignment in unions.
} else {
// Allocate a new block of memory and place the bitfield in it.
CharUnits FieldOffset = Size.RoundUpToAlignment(Info.Alignment);
placeFieldAtOffset(FieldOffset);
Size = FieldOffset + Info.Size;
+ Alignment = std::max(Alignment, Info.Alignment);
RemainingBitsInField = Context.toBits(Info.Size) - Width;
}
}
@@ -2531,11 +2531,13 @@ MicrosoftRecordLayoutBuilder::layoutZeroWidthBitField(const FieldDecl *FD) {
if (IsUnion) {
placeFieldAtOffset(CharUnits::Zero());
Size = std::max(Size, Info.Size);
+ // TODO: Add a Sema warning that MS ignores bitfield alignment in unions.
} else {
// Round up the current record size to the field's alignment boundary.
CharUnits FieldOffset = Size.RoundUpToAlignment(Info.Alignment);
placeFieldAtOffset(FieldOffset);
Size = FieldOffset;
+ Alignment = std::max(Alignment, Info.Alignment);
}
}
diff --git a/clang/test/Sema/ms_bitfield_layout.c b/clang/test/Sema/ms_bitfield_layout.c
index f2010c16225..8444f469d59 100644
--- a/clang/test/Sema/ms_bitfield_layout.c
+++ b/clang/test/Sema/ms_bitfield_layout.c
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts %s 2>/dev/null \
+// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fms-extensions -fdump-record-layouts %s 2>/dev/null \
// RUN: | FileCheck %s
-// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts %s 2>/dev/null \
+// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fms-extensions -fdump-record-layouts %s 2>/dev/null \
// RUN: | FileCheck %s
typedef struct A {
@@ -111,6 +111,16 @@ typedef struct H {
// CHECK: Alignment:16
// CHECK: FieldOffsets: [0, 16, 16, 16]>
+typedef struct I {
+ short : 8;
+ __declspec(align(16)) short : 8;
+} I;
+
+// CHECK: Type: struct I
+// CHECK: Size:16
+// CHECK: Alignment:16
+// CHECK: FieldOffsets: [0, 8]
+
#pragma pack(push, 1)
typedef struct A1 {
@@ -221,6 +231,16 @@ typedef struct H1 {
// CHECK: Alignment:8
// CHECK: FieldOffsets: [0, 32, 32, 32]>
+typedef struct I1 {
+ short : 8;
+ __declspec(align(16)) short : 8;
+} I1;
+
+// CHECK: Type: struct I1
+// CHECK: Size:16
+// CHECK: Alignment:8
+// CHECK: FieldOffsets: [0, 8]
+
#pragma pack(pop)
int x[
@@ -232,6 +252,7 @@ sizeof(E ) +
sizeof(F ) +
sizeof(G ) +
sizeof(H ) +
+sizeof(I ) +
sizeof(A1) +
sizeof(B1) +
sizeof(C1) +
@@ -240,4 +261,5 @@ sizeof(E1) +
sizeof(F1) +
sizeof(G1) +
sizeof(H1) +
+sizeof(I1) +
0];
OpenPOWER on IntegriCloud