From d18d1517f601ae5b2249ca1bd4e6db906cf3985e Mon Sep 17 00:00:00 2001 From: Warren Hunt Date: Mon, 13 Jan 2014 22:25:55 +0000 Subject: [PATCH] [ms-abi] Reordering __declspec(align) pragma pack handling This patch moves the check for pragma pack until after the application of __declspec align to before pragma pack. This causes observable changes in the use of tail padding for bases. A test case is included. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@199154 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AST/RecordLayoutBuilder.cpp | 6 ++--- test/Layout/ms-x86-pack-and-align.cpp | 33 +++++++++++++++++++++++++-- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp index e9289a0f05..fd0a463012 100644 --- a/lib/AST/RecordLayoutBuilder.cpp +++ b/lib/AST/RecordLayoutBuilder.cpp @@ -2186,9 +2186,6 @@ MicrosoftRecordLayoutBuilder::getAdjustedElementInfo( Context.getTypeInfoInChars(FD->getType()); if (FD->isBitField() && FD->getMaxAlignment() != 0) Info.Alignment = std::max(Info.Alignment, FieldRequiredAlignment); - // Respect pragma pack. - if (!MaxFieldAlignment.isZero()) - Info.Alignment = std::min(Info.Alignment, MaxFieldAlignment); } // Respect packed field attribute. if (FD->hasAttr()) @@ -2200,6 +2197,9 @@ MicrosoftRecordLayoutBuilder::getAdjustedElementInfo( // Capture required alignment as a side-effect. RequiredAlignment = std::max(RequiredAlignment, FieldRequiredAlignment); } + // Respect pragma pack. + if (!MaxFieldAlignment.isZero()) + Info.Alignment = std::min(Info.Alignment, MaxFieldAlignment); // TODO: Add a Sema warning that MS ignores bitfield alignment in unions. if (!(FD->isBitField() && IsUnion)) Alignment = std::max(Alignment, Info.Alignment); diff --git a/test/Layout/ms-x86-pack-and-align.cpp b/test/Layout/ms-x86-pack-and-align.cpp index 5c2710e6d6..cd376adb38 100644 --- a/test/Layout/ms-x86-pack-and-align.cpp +++ b/test/Layout/ms-x86-pack-and-align.cpp @@ -43,7 +43,7 @@ struct X { // CHECK: 8 | char b // CHECK-NEXT: 10 | int c // CHECK-NEXT: | [sizeof=16, align=4 -// CHECK-NEXT: | nvsize=16, nvalign=4] +// CHECK-NEXT: | nvsize=14, nvalign=4] // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64: *** Dumping AST Record Layout // CHECK-X64-NEXT: 0 | struct X @@ -52,7 +52,7 @@ struct X { // CHECK-X64: 8 | char b // CHECK-X64-NEXT: 10 | int c // CHECK-X64-NEXT: | [sizeof=16, align=4 -// CHECK-X64-NEXT: | nvsize=16, nvalign=4] +// CHECK-X64-NEXT: | nvsize=14, nvalign=4] struct Y : A, B { char a; @@ -321,6 +321,34 @@ struct D2 : D1 { char a; }; // CHECK-X64-NEXT: | [sizeof=16, align=16 // CHECK-X64-NEXT: | nvsize=16, nvalign=16] +#pragma pack() +struct JA { char a; }; +#pragma pack(1) +struct JB { __declspec(align(4)) char a; }; +#pragma pack() +struct JC : JB, JA { }; + +// CHECK: *** Dumping AST Record Layout +// CHECK: *** Dumping AST Record Layout +// CHECK: *** Dumping AST Record Layout +// CHECK-NEXT: 0 | struct JC +// CHECK-NEXT: 0 | struct JB (base) +// CHECK-NEXT: 0 | char a +// CHECK-NEXT: 1 | struct JA (base) +// CHECK-NEXT: 1 | char a +// CHECK-NEXT: | [sizeof=4, align=4 +// CHECK-NEXT: | nvsize=4, nvalign=4] +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64: *** Dumping AST Record Layout +// CHECK-X64-NEXT: 0 | struct JC +// CHECK-X64-NEXT: 0 | struct JB (base) +// CHECK-X64-NEXT: 0 | char a +// CHECK-X64-NEXT: 1 | struct JA (base) +// CHECK-X64-NEXT: 1 | char a +// CHECK-X64-NEXT: | [sizeof=4, align=4 +// CHECK-X64-NEXT: | nvsize=4, nvalign=4] + int a[ sizeof(X)+ sizeof(Y)+ @@ -335,4 +363,5 @@ sizeof(YE)+ sizeof(YF)+ sizeof(YF)+ sizeof(D2)+ +sizeof(JC)+ 0]; -- 2.40.0