[PATCH] D14872: PR25575: Make GCC 4.4+ comatible layout for packed bit-fileds of char type

Dmitry Polukhin via cfe-commits cfe-commits at lists.llvm.org
Thu Nov 26 02:47:28 PST 2015


DmitryPolukhin updated this revision to Diff 41222.
DmitryPolukhin marked 2 inline comments as done.
DmitryPolukhin added a comment.

Changed note text message + fixed outdated comment.


http://reviews.llvm.org/D14872

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

Index: test/Sema/struct-packed-align.c
===================================================================
--- test/Sema/struct-packed-align.c
+++ test/Sema/struct-packed-align.c
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 %s -fsyntax-only -verify
-// expected-no-diagnostics
+// RUN: %clang_cc1 %s -fsyntax-only -triple=x86_64-windows-coff -verify
 
 // Packed structs.
 struct s {
@@ -138,3 +138,24 @@
 extern int n1[sizeof(struct nS) == 9 ? 1 : -1];
 extern int n2[__alignof(struct nS) == 1 ? 1 : -1];
 #endif
+
+// Packed attribute shouldn't be ignored for bit-field of char types.
+// Note from GCC reference manual: The 4.1, 4.2 and 4.3 series of GCC ignore
+// the packed attribute on bit-fields of type char. This has been fixed in
+// GCC 4.4 but the change can lead to differences in the structure layout.
+// See the documentation of -Wpacked-bitfield-compat for more information.
+struct packed_chars {
+  char a:4;
+  char b:8 __attribute__ ((packed));
+  // expected-warning at -1 {{the offset assigned to packed bit-field member 'b' changed with GCC version 4.4 - the newer offset is used here}}
+  char c:4;
+};
+
+#if defined(_WIN32)
+// On Windows clang ignores uses MSVC compatible layout in this case.
+extern int o1[sizeof(struct packed_chars) == 3 ? 1 : -1];
+extern int o2[__alignof(struct packed_chars) == 1 ? 1 : -1];
+#else
+extern int o1[sizeof(struct packed_chars) == 2 ? 1 : -1];
+extern int o2[__alignof(struct packed_chars) == 1 ? 1 : -1];
+#endif
Index: lib/Sema/SemaDeclAttr.cpp
===================================================================
--- lib/Sema/SemaDeclAttr.cpp
+++ lib/Sema/SemaDeclAttr.cpp
@@ -1036,17 +1036,17 @@
     TD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context,
                                         Attr.getAttributeSpellingListIndex()));
   else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
-    // If the alignment is less than or equal to 8 bits, the packed attribute
-    // has no effect.
+    // 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_ignored_for_field_of_type)
-        << Attr.getName() << FD->getType();
-    else
-      FD->addAttr(::new (S.Context)
-                  PackedAttr(Attr.getRange(), S.Context,
-                             Attr.getAttributeSpellingListIndex()));
+      S.Diag(Attr.getLoc(),
+             diag::note_attribute_packed_for_bitfield_offset_changed)
+        << FD->getDeclName();
+
+    FD->addAttr(::new (S.Context) PackedAttr(
+        Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex()));
   } else
     S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
 }
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -2780,9 +2780,10 @@
   "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 note_attribute_packed_for_bitfield_offset_changed : Warning<
+  "the offset assigned to packed bit-field member %0 changed with GCC "
+  "version 4.4 - the newer offset is used here">,
+  InGroup<DiagGroup<"attribute-packed-for-bitfield-offset-changed">>;
 def warn_transparent_union_attribute_field_size_align : Warning<
   "%select{alignment|size}0 of field %1 (%2 bits) does not match the "
   "%select{alignment|size}0 of the first field in transparent union; "


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D14872.41222.patch
Type: text/x-patch
Size: 3784 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20151126/fed9d887/attachment-0001.bin>


More information about the cfe-commits mailing list