[clang] 798fe3c - [PowerPC][AIX] Fix Zero-width bit fields wrt MaxFieldAlign.

Steven Wan via cfe-commits cfe-commits at lists.llvm.org
Mon Jul 12 12:32:34 PDT 2021


Author: Steven Wan
Date: 2021-07-12T15:31:15-04:00
New Revision: 798fe3c774a1af75c8735933ded749fa62f39594

URL: https://github.com/llvm/llvm-project/commit/798fe3c774a1af75c8735933ded749fa62f39594
DIFF: https://github.com/llvm/llvm-project/commit/798fe3c774a1af75c8735933ded749fa62f39594.diff

LOG: [PowerPC][AIX] Fix Zero-width bit fields wrt MaxFieldAlign.

On AIX when there is a pragma pack, or pragma align in effect then zero-width bitfields should pad out to the end of the bitfield container but not increase the alignment requirements of the struct greater then the max field align.

Reviewed By: ZarkoCA

Differential Revision: https://reviews.llvm.org/D105635

Added: 
    clang/test/Layout/aix-packed-bitfields.c

Modified: 
    clang/lib/AST/RecordLayoutBuilder.cpp
    clang/test/Layout/aix-bitfield-alignment.c

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp
index 6ee4178248b92..972690becf9ec 100644
--- a/clang/lib/AST/RecordLayoutBuilder.cpp
+++ b/clang/lib/AST/RecordLayoutBuilder.cpp
@@ -1775,6 +1775,12 @@ void ItaniumRecordLayoutBuilder::LayoutBitField(const FieldDecl *D) {
       !D->getIdentifier())
     FieldAlign = UnpackedFieldAlign = 1;
 
+  // On AIX, zero-width bitfields pad out to the alignment boundary, but then
+  // do not affect overall record alignment if there is a pragma pack or
+  // pragma align(packed).
+  if (isAIXLayout(Context) && !MaxFieldAlignment.isZero() && !FieldSize)
+    FieldAlign = std::min(FieldAlign, MaxFieldAlignmentInBits);
+
   // Diagnose 
diff erences in layout due to padding or packing.
   if (!UseExternalLayout)
     CheckFieldPadding(FieldOffset, UnpaddedFieldOffset, UnpackedFieldOffset,

diff  --git a/clang/test/Layout/aix-bitfield-alignment.c b/clang/test/Layout/aix-bitfield-alignment.c
index a736695cc6030..d47b3d7a0c7d8 100644
--- a/clang/test/Layout/aix-bitfield-alignment.c
+++ b/clang/test/Layout/aix-bitfield-alignment.c
@@ -232,3 +232,37 @@ int s = sizeof(G);
 // CHECK-NEXT:          0 | struct G
 // CHECK-NEXT:     0:0-44 |   long long ll
 // CHECK-NEXT:               sizeof=8, {{(dsize=8, )?}}align=8, preferredalign=8
+
+#pragma align(packed)
+struct H {
+   char c;
+   int : 0;
+   int i;
+} H;
+#pragma align(reset)
+
+int h = sizeof(H);
+
+// CHECK:      *** Dumping AST Record Layout
+// CHECK-NEXT:          0 | struct H
+// CHECK-NEXT:          0 |   char c
+// CHECK-NEXT:        4:- |   int
+// CHECK-NEXT:          4 |   int i
+// CHECK-NEXT:              sizeof=8, {{(dsize=8, )?}}align=1, preferredalign=1
+
+#pragma pack(2)
+struct I {
+   char c;
+   int : 0;
+   int i;
+} I;
+#pragma pack(pop)
+
+int i = sizeof(I);
+
+// CHECK:      *** Dumping AST Record Layout
+// CHECK-NEXT:          0 | struct I
+// CHECK-NEXT:          0 |   char c
+// CHECK-NEXT:        4:- |   int
+// CHECK-NEXT:          4 |   int i
+// CHECK-NEXT:              sizeof=8, {{(dsize=8, )?}}align=2, preferredalign=2

diff  --git a/clang/test/Layout/aix-packed-bitfields.c b/clang/test/Layout/aix-packed-bitfields.c
new file mode 100644
index 0000000000000..9bc907af0f596
--- /dev/null
+++ b/clang/test/Layout/aix-packed-bitfields.c
@@ -0,0 +1,77 @@
+// RUN: %clang_cc1 -triple powerpc-ibm-aix-xcoff -fdump-record-layouts \
+// RUN:     -fsyntax-only -fxl-pragma-pack -x c %s | FileCheck  %s
+
+// RUN: %clang_cc1 -triple powerpc-ibm-aix-xcoff -fdump-record-layouts \
+// RUN:     -fsyntax-only -fxl-pragma-pack -x c++ %s | FileCheck %s
+//
+// RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -fdump-record-layouts \
+// RUN:     -fsyntax-only -fxl-pragma-pack -x c %s | FileCheck  %s
+//
+// RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -fdump-record-layouts \
+// RUN:     -fsyntax-only -fxl-pragma-pack -x c++ %s | FileCheck %s
+
+struct A {
+  int a1 : 30;
+  int a2 : 30;
+  int a3 : 4;
+};
+
+int a = sizeof(struct A);
+
+// CHECK:      *** Dumping AST Record Layout
+// CHECK-NEXT:      0 | struct A
+// CHECK-NEXT: 0:0-29 |   int a1
+// CHECK-NEXT: 4:0-29 |   int a2
+// CHECK-NEXT:  8:0-3 |   int a3
+// CHECK-NEXT:          sizeof=12, {{(dsize=12, )?}}align=4, preferredalign=4
+
+#pragma align(packed)
+struct AlignPacked {
+  int a1 : 30;
+  int a2 : 30;
+  int a3 : 4;
+};
+#pragma align(reset)
+
+int b = sizeof(struct AlignPacked);
+
+// CHECK:      *** Dumping AST Record Layout
+// CHECK-NEXT:      0 | struct AlignPacked
+// CHECK-NEXT: 0:0-29 |   int a1
+// CHECK-NEXT: 3:6-35 |   int a2
+// CHECK-NEXT:  7:4-7 |   int a3
+// CHECK-NEXT:          sizeof=8, {{(dsize=8, )?}}align=1, preferredalign=1
+
+#pragma pack(1)
+struct Pack1 {
+  int a1 : 30;
+  int a2 : 30;
+  int a3 : 4;
+};
+#pragma pack(pop)
+
+int c = sizeof(struct Pack1);
+
+// CHECK:      *** Dumping AST Record Layout
+// CHECK-NEXT:      0 | struct Pack1
+// CHECK-NEXT: 0:0-29 |   int a1
+// CHECK-NEXT: 3:6-35 |   int a2
+// CHECK-NEXT:  7:4-7 |   int a3
+// CHECK-NEXT:          sizeof=8, {{(dsize=8, )?}}align=1, preferredalign=1
+
+#pragma pack(2)
+struct Pack2 {
+  int a1 : 30;
+  int a2 : 30;
+  int a3 : 4;
+};
+#pragma pack(pop)
+
+int d = sizeof(struct Pack2);
+
+// CHECK:      *** Dumping AST Record Layout
+// CHECK-NEXT:      0 | struct Pack2
+// CHECK-NEXT: 0:0-29 |   int a1
+// CHECK-NEXT: 3:6-35 |   int a2
+// CHECK-NEXT:  7:4-7 |   int a3
+// CHECK-NEXT:          sizeof=8, {{(dsize=8, )?}}align=2, preferredalign=2


        


More information about the cfe-commits mailing list