r206132 - MS ABI: Bitfields FielDecls only align if they allocate

David Majnemer david.majnemer at gmail.com
Sun Apr 13 01:15:50 PDT 2014


Author: majnemer
Date: Sun Apr 13 03:15:50 2014
New Revision: 206132

URL: http://llvm.org/viewvc/llvm-project?rev=206132&view=rev
Log:
MS ABI: Bitfields FielDecls only align if they allocate

Don't consider a __declspec(align) on a bitfield's declaration if it didn't
allocate any underlying storage.

This fixes PR19414.

Modified:
    cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
    cfe/trunk/test/Sema/ms_bitfield_layout.c

Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.cpp?rev=206132&r1=206131&r2=206132&view=diff
==============================================================================
--- cfe/trunk/lib/AST/RecordLayoutBuilder.cpp (original)
+++ cfe/trunk/lib/AST/RecordLayoutBuilder.cpp Sun Apr 13 03:15:50 2014
@@ -2291,9 +2291,6 @@ MicrosoftRecordLayoutBuilder::getAdjuste
   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::layou
   }
   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::layou
   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::layoutZero
   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);
   }
 }
 

Modified: cfe/trunk/test/Sema/ms_bitfield_layout.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/ms_bitfield_layout.c?rev=206132&r1=206131&r2=206132&view=diff
==============================================================================
--- cfe/trunk/test/Sema/ms_bitfield_layout.c (original)
+++ cfe/trunk/test/Sema/ms_bitfield_layout.c Sun Apr 13 03:15:50 2014
@@ -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];





More information about the cfe-commits mailing list