[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