]> granicus.if.org Git - clang/commitdiff
[ms-abi] Reordering __declspec(align) pragma pack handling
authorWarren Hunt <whunt@google.com>
Mon, 13 Jan 2014 22:25:55 +0000 (22:25 +0000)
committerWarren Hunt <whunt@google.com>
Mon, 13 Jan 2014 22:25:55 +0000 (22:25 +0000)
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
test/Layout/ms-x86-pack-and-align.cpp

index e9289a0f055dcac953b1a9d2f888ee436951c5ea..fd0a46301253e2a60eee9e75b0a1a7a2977d7eff 100644 (file)
@@ -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<PackedAttr>())
@@ -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);
index 5c2710e6d6232844c31985afc53e4fa4ac2d8b3b..cd376adb38102a0696eb20406f236b8902224218 100644 (file)
@@ -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];