]> granicus.if.org Git - clang/commitdiff
Restore previous structure ABI behavior for bit-fields with the packed attribute...
authorAaron Ballman <aaron@aaronballman.com>
Tue, 8 Aug 2017 18:07:17 +0000 (18:07 +0000)
committerAaron Ballman <aaron@aaronballman.com>
Tue, 8 Aug 2017 18:07:17 +0000 (18:07 +0000)
An ABI change was introduced in r254596 that modified structure layouts when the 'packed' attribute was used on one-byte bitfields. Since the PS4 target needs to maintain backwards compatibility for all structure layouts, this change reintroduces the old behavior for PS4 targets only. It also introduces PS4 specific cases to the relevant test.

Patch by Matthew Voss.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@310388 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDeclAttr.cpp
test/Sema/struct-packed-align.c

index a07be3f82cd1f5b988da21ad2c09604fc400fd6b..74ea2d5fd53f880b335cf5b072c7314dc0e8db24 100644 (file)
@@ -3202,6 +3202,9 @@ def warn_int_to_void_pointer_cast : Warning<
   "cast to %1 from smaller integer type %0">,
   InGroup<IntToVoidPointerCast>;
 
+def warn_attribute_ignored_for_field_of_type : Warning<
+  "%0 attribute ignored for field of type %1">,
+  InGroup<IgnoredAttributes>;
 def warn_no_underlying_type_specified_for_enum_bitfield : Warning<
   "enums in the Microsoft ABI are signed integers by default; consider giving "
   "the enum %0 an unsigned underlying type to make this code portable">,
index 6e29717643b5b7922030547b5a64916fdbd803f3..cef84116db3740b3ac955d5eb500b43c51086bec 100644 (file)
@@ -1304,14 +1304,28 @@ static void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
     TD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context,
                                         Attr.getAttributeSpellingListIndex()));
   else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
-    // Report warning about changed offset in the newer compiler versions.
-    if (!FD->getType()->isDependentType() &&
-        !FD->getType()->isIncompleteType() && FD->isBitField() &&
-        S.Context.getTypeAlign(FD->getType()) <= 8)
-      S.Diag(Attr.getLoc(), diag::warn_attribute_packed_for_bitfield);
+    bool BitfieldByteAligned = (!FD->getType()->isDependentType() &&
+                                !FD->getType()->isIncompleteType() &&
+                                FD->isBitField() &&
+                                S.Context.getTypeAlign(FD->getType()) <= 8);
+
+    if (S.getASTContext().getTargetInfo().getTriple().isPS4()) {
+      if (BitfieldByteAligned)
+        // The PS4 target needs to maintain ABI backwards compatibility.
+        S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
+          << Attr.getName() << FD->getType();
+      else
+        FD->addAttr(::new (S.Context) PackedAttr(
+                    Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex()));
+    } else {
+      // Report warning about changed offset in the newer compiler versions.
+      if (BitfieldByteAligned)
+        S.Diag(Attr.getLoc(), diag::warn_attribute_packed_for_bitfield);
+
+      FD->addAttr(::new (S.Context) PackedAttr(
+                  Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex()));
+    }
 
-    FD->addAttr(::new (S.Context) PackedAttr(
-        Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex()));
   } else
     S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
 }
index abdcd8e6b9eb1ac8387b5068c2c289373fc9beb1..aeba8d6fd938445ca9663838e515f7e795e24a74 100644 (file)
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 %s -fsyntax-only -verify
 // RUN: %clang_cc1 %s -fsyntax-only -triple=x86_64-windows-coff -verify
+// RUN: %clang_cc1 %s -fsyntax-only -triple=x86_64-scei-ps4 -verify
 
 // Packed structs.
 struct s {
@@ -146,13 +147,24 @@ extern int n2[__alignof(struct nS) == 1 ? 1 : -1];
 // See the documentation of -Wpacked-bitfield-compat for more information.
 struct packed_chars {
   char a:4;
+#ifdef __ORBIS__
+  // Test for pre-r254596 clang behavior on the PS4 target. PS4 must maintain
+  // ABI backwards compatibility.
+  char b:8 __attribute__ ((packed));
+  // expected-warning@-1 {{'packed' attribute ignored for field of type 'char'}}
+  char c:4;
+#else
   char b:8 __attribute__ ((packed));
   // expected-warning@-1 {{'packed' attribute was ignored on bit-fields with single-byte alignment in older versions of GCC and Clang}}
   char c:4;
+#endif
 };
 
-#if defined(_WIN32) && !defined(__declspec) // _MSC_VER is unavailable in cc1.
+#if (defined(_WIN32) || defined(__ORBIS__)) && !defined(__declspec) // _MSC_VER is unavailable in cc1.
 // On Windows clang uses MSVC compatible layout in this case.
+//
+// Additionally, test for pre-r254596 clang behavior on the PS4 target. PS4
+// must maintain ABI backwards compatibility.
 extern int o1[sizeof(struct packed_chars) == 3 ? 1 : -1];
 extern int o2[__alignof(struct packed_chars) == 1 ? 1 : -1];
 #else