OSDN Git Service

* c-decl.c (finish_struct): Move code to set DECL_PACKED after
authornemet <nemet@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 23 Jan 2009 06:29:54 +0000 (06:29 +0000)
committernemet <nemet@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 23 Jan 2009 06:29:54 +0000 (06:29 +0000)
DECL_BIT_FIELD is alreay known.  Also inherit packed for bitfields
regardless of their type.
* c-common.c (handle_packed_attribute): Don't ignore packed on
bitfields.
* c.opt (Wpacked-bitfield-compat): New warning option.
* stor-layout.c (place_field): Warn if offset of a field changed.
* doc/extend.texi (packed): Mention the ABI change.
* doc/invoke.texi (-Wpacked-bitfield-compat): Document.
(Warning Options): Add it to the list.

cp/
* class.c (check_field_decls): Also inherit packed for bitfields
regardless of their type.

testsuite/
* gcc.dg/bitfld-15.c, gcc.dg/bitfld-16.c,
gcc.dg/bitfld-17.c,gcc.dg/bitfld-18.c: New tests.
* g++.dg/ext/bitfield2.C, g++.dg/ext/bitfield3.C,
g++.dg/ext/bitfield4.C, g++.dg/ext/bitfield5.C: New tests.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@143584 138bc75d-0d04-0410-961f-82ee72b054a4

18 files changed:
gcc/ChangeLog
gcc/c-common.c
gcc/c-decl.c
gcc/c.opt
gcc/cp/ChangeLog
gcc/cp/class.c
gcc/doc/extend.texi
gcc/doc/invoke.texi
gcc/stor-layout.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/bitfield2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/bitfield3.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/bitfield4.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/bitfield5.C [new file with mode: 0644]
gcc/testsuite/gcc.dg/bitfld-15.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/bitfld-16.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/bitfld-17.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/bitfld-18.c [new file with mode: 0644]

index 3136439..2cfe41a 100644 (file)
@@ -1,3 +1,16 @@
+2009-01-22  Adam Nemet  <anemet@caviumnetworks.com>
+
+       * c-decl.c (finish_struct): Move code to set DECL_PACKED after
+       DECL_BIT_FIELD is alreay known.  Also inherit packed for bitfields
+       regardless of their type.
+       * c-common.c (handle_packed_attribute): Don't ignore packed on
+       bitfields.
+       * c.opt (Wpacked-bitfield-compat): New warning option.
+       * stor-layout.c (place_field): Warn if offset of a field changed.
+       * doc/extend.texi (packed): Mention the ABI change.
+       * doc/invoke.texi (-Wpacked-bitfield-compat): Document.
+       (Warning Options): Add it to the list.
+
 2009-01-22  H.J. Lu  <hongjiu.lu@intel.com>
 
        * c-opts.c (c_common_post_options): Fix a typo in comments.
index 5eed1dc..81992d4 100644 (file)
@@ -5113,7 +5113,9 @@ handle_packed_attribute (tree *node, tree name, tree ARG_UNUSED (args),
     }
   else if (TREE_CODE (*node) == FIELD_DECL)
     {
-      if (TYPE_ALIGN (TREE_TYPE (*node)) <= BITS_PER_UNIT)
+      if (TYPE_ALIGN (TREE_TYPE (*node)) <= BITS_PER_UNIT
+         /* Still pack bitfields.  */
+         && ! DECL_INITIAL (*node))
        warning (OPT_Wattributes,
                 "%qE attribute ignored for field of type %qT",
                 name, TREE_TYPE (*node));
index 7f7f2b0..6ebee1a 100644 (file)
@@ -5564,9 +5564,6 @@ finish_struct (tree t, tree fieldlist, tree attributes)
 
       DECL_CONTEXT (x) = t;
 
-      if (TYPE_PACKED (t) && TYPE_ALIGN (TREE_TYPE (x)) > BITS_PER_UNIT)
-       DECL_PACKED (x) = 1;
-
       /* If any field is const, the structure type is pseudo-const.  */
       if (TREE_READONLY (x))
        C_TYPE_FIELDS_READONLY (t) = 1;
@@ -5598,6 +5595,11 @@ finish_struct (tree t, tree fieldlist, tree attributes)
          SET_DECL_C_BIT_FIELD (x);
        }
 
+      if (TYPE_PACKED (t)
+         && (DECL_BIT_FIELD (x)
+             || TYPE_ALIGN (TREE_TYPE (x)) > BITS_PER_UNIT))
+       DECL_PACKED (x) = 1;
+
       /* Detect flexible array member in an invalid context.  */
       if (TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE
          && TYPE_SIZE (TREE_TYPE (x)) == NULL_TREE
index 1888ecd..75b7042 100644 (file)
--- a/gcc/c.opt
+++ b/gcc/c.opt
@@ -364,6 +364,10 @@ Woverride-init
 C ObjC Var(warn_override_init) Init(-1) Warning
 Warn about overriding initializers without side effects
 
+Wpacked-bitfield-compat
+C ObjC C++ ObjC++ Var(warn_packed_bitfield_compat) Init(1) Warning
+Warn about packed bit-fields whose offset changed in GCC 4.4
+
 Wparentheses
 C ObjC C++ ObjC++ Var(warn_parentheses) Warning
 Warn about possibly missing parentheses
index a7d18d2..876cb7f 100644 (file)
@@ -1,3 +1,8 @@
+2009-01-22  Adam Nemet  <anemet@caviumnetworks.com>
+
+       * class.c (check_field_decls): Also inherit packed for bitfields
+       regardless of their type.
+
 2009-01-22  Dodji Seketeli  <dodji@redhat.com>
 
        PR c++/38930
index 8d326f2..f56edc3 100644 (file)
@@ -2974,7 +2974,8 @@ check_field_decls (tree t, tree *access_decls,
                 x);
              cant_pack = 1;
            }
-         else if (TYPE_ALIGN (TREE_TYPE (x)) > BITS_PER_UNIT)
+         else if (DECL_C_BIT_FIELD (x)
+                  || TYPE_ALIGN (TREE_TYPE (x)) > BITS_PER_UNIT)
            DECL_PACKED (x) = 1;
        }
 
index 264e88a..79a8c2e 100644 (file)
@@ -3824,6 +3824,12 @@ struct foo
 @};
 @end smallexample
 
+@emph{Note:} The 4.1, 4.2 and 4.3 series of GCC ignore the
+@code{packed} attribute on bit-fields of type @code{char}.  This has
+been fixed in GCC 4.4 but the change can lead to differences in the
+structure layout.  See the documention of
+@option{-Wpacked-bitfield-compat} for more information.
+
 @item section ("@var{section-name}")
 @cindex @code{section} variable attribute
 Normally, the compiler places the objects it generates in sections like
index b0e274c..247782a 100644 (file)
@@ -249,7 +249,7 @@ Objective-C and Objective-C++ Dialects}.
 -Wmissing-format-attribute  -Wmissing-include-dirs @gol
 -Wmissing-noreturn  -Wno-mudflap @gol
 -Wno-multichar  -Wnonnull  -Wno-overflow @gol
--Woverlength-strings  -Wpacked  -Wpadded @gol
+-Woverlength-strings  -Wpacked  -Wpacked-bitfield-compat  -Wpadded @gol
 -Wparentheses  -Wpedantic-ms-format -Wno-pedantic-ms-format @gol
 -Wpointer-arith  -Wno-pointer-to-int-cast @gol
 -Wredundant-decls @gol
@@ -3974,6 +3974,27 @@ struct bar @{
 @end group
 @end smallexample
 
+@item -Wpacked-bitfield-compat
+@opindex Wpacked-bitfield-compat
+@opindex Wno-packed-bitfield-compat
+The 4.1, 4.2 and 4.3 series of GCC ignore the @code{packed} attribute
+on bit-fields of type @code{char}.  This has been fixed in GCC 4.4 but
+the change can lead to differences in the structure layout.  GCC
+informs you when the offset of such a field has changed in GCC 4.4.
+For example there is no longer a 4-bit padding between field @code{a}
+and @code{b} in this structure:
+
+@smallexample
+struct foo
+@{
+  char a:4;
+  char b:8;
+@} __attribute__ ((packed));
+@end smallexample
+
+This warning is enabled by default.  Use
+@option{-Wno-packed-bitfield-compat} to disable this warning.
+
 @item -Wpadded
 @opindex Wpadded
 @opindex Wno-padded
index 0e7caa5..bf896db 100644 (file)
@@ -937,7 +937,9 @@ place_field (record_layout_info rli, tree field)
       && TREE_CODE (field) == FIELD_DECL
       && type != error_mark_node
       && DECL_BIT_FIELD (field)
-      && ! DECL_PACKED (field)
+      && (! DECL_PACKED (field)
+         /* Enter for these packed fields only to issue a warning.  */
+         || TYPE_ALIGN (type) <= BITS_PER_UNIT)
       && maximum_field_alignment == 0
       && ! integer_zerop (DECL_SIZE (field))
       && host_integerp (DECL_SIZE (field), 1)
@@ -958,9 +960,21 @@ place_field (record_layout_info rli, tree field)
       /* A bit field may not span more units of alignment of its type
         than its type itself.  Advance to next boundary if necessary.  */
       if (excess_unit_span (offset, bit_offset, field_size, type_align, type))
-       rli->bitpos = round_up (rli->bitpos, type_align);
+       {
+         if (DECL_PACKED (field))
+           {
+             if (warn_packed_bitfield_compat)
+               inform
+                 (input_location,
+                  "Offset of packed bit-field %qD has changed in GCC 4.4",
+                  field);
+           }
+         else
+           rli->bitpos = round_up (rli->bitpos, type_align);
+       }
 
-      TYPE_USER_ALIGN (rli->t) |= TYPE_USER_ALIGN (type);
+      if (! DECL_PACKED (field))
+       TYPE_USER_ALIGN (rli->t) |= TYPE_USER_ALIGN (type);
     }
 #endif
 
index 37c8b09..bbf10c4 100644 (file)
@@ -1,3 +1,10 @@
+2009-01-22  Adam Nemet  <anemet@caviumnetworks.com>
+
+       * gcc.dg/bitfld-15.c, gcc.dg/bitfld-16.c,
+       gcc.dg/bitfld-17.c,gcc.dg/bitfld-18.c: New tests.
+       * g++.dg/ext/bitfield2.C, g++.dg/ext/bitfield3.C,
+       g++.dg/ext/bitfield4.C, g++.dg/ext/bitfield5.C: New tests.
+
 2009-01-22  Steve Ellcey  <sje@cup.hp.com>
 
        * gcc.dg/pr35729.c: Make test x86 specific.
diff --git a/gcc/testsuite/g++.dg/ext/bitfield2.C b/gcc/testsuite/g++.dg/ext/bitfield2.C
new file mode 100644 (file)
index 0000000..2b827a3
--- /dev/null
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* Remove pedantic.  Allow the GCC extension to use char for bitfields.  */
+/* { dg-options "" } */
+
+struct t
+{                              /* { dg-message "note: Offset of packed bit-field 't::b' has changed in GCC 4.4" "" } */
+  char a:4;
+  char b:8;
+  char c:4;
+} __attribute__ ((packed));
+
+int assrt[sizeof (struct t) == 2 ? 1 : -1];
diff --git a/gcc/testsuite/g++.dg/ext/bitfield3.C b/gcc/testsuite/g++.dg/ext/bitfield3.C
new file mode 100644 (file)
index 0000000..3b30cc9
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-Wno-packed-bitfield-compat" } */
+
+struct t
+{
+  char a:4;
+  char b:8;
+  char c:4;
+} __attribute__ ((packed));
+
+int assrt[sizeof (struct t) == 2 ? 1 : -1];
diff --git a/gcc/testsuite/g++.dg/ext/bitfield4.C b/gcc/testsuite/g++.dg/ext/bitfield4.C
new file mode 100644 (file)
index 0000000..f5fbd82
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+struct t
+{                              /* { dg-message "note: Offset of packed bit-field 't::b' has changed in GCC 4.4" "" } */
+  char a:4;
+  char b:8 __attribute__ ((packed));
+  char c:4;
+};
+
+int assrt[sizeof (struct t) == 2 ? 1 : -1];
diff --git a/gcc/testsuite/g++.dg/ext/bitfield5.C b/gcc/testsuite/g++.dg/ext/bitfield5.C
new file mode 100644 (file)
index 0000000..2cd8e7d
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-Wno-packed-bitfield-compat" } */
+
+struct t
+{
+  char a:4;
+  char b:8 __attribute__ ((packed));
+  char c:4;
+};
+
+int assrt[sizeof (struct t) == 2 ? 1 : -1];
diff --git a/gcc/testsuite/gcc.dg/bitfld-15.c b/gcc/testsuite/gcc.dg/bitfld-15.c
new file mode 100644 (file)
index 0000000..bceeead
--- /dev/null
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* Remove pedantic.  Allow the GCC extension to use char for bitfields.  */
+/* { dg-options "" } */
+
+struct t
+{
+  char a:4;
+  char b:8;
+  char c:4;
+} __attribute__ ((packed));    /* { dg-message "note: Offset of packed bit-field 'b' has changed in GCC 4.4" "" } */
+
+int assrt[sizeof (struct t) == 2 ? 1 : -1];
diff --git a/gcc/testsuite/gcc.dg/bitfld-16.c b/gcc/testsuite/gcc.dg/bitfld-16.c
new file mode 100644 (file)
index 0000000..3b30cc9
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-Wno-packed-bitfield-compat" } */
+
+struct t
+{
+  char a:4;
+  char b:8;
+  char c:4;
+} __attribute__ ((packed));
+
+int assrt[sizeof (struct t) == 2 ? 1 : -1];
diff --git a/gcc/testsuite/gcc.dg/bitfld-17.c b/gcc/testsuite/gcc.dg/bitfld-17.c
new file mode 100644 (file)
index 0000000..88ec199
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+struct t
+{
+  char a:4;
+  char b:8 __attribute__ ((packed));
+  char c:4;
+};                             /* { dg-message "note: Offset of packed bit-field 'b' has changed in GCC 4.4" "" } */
+
+int assrt[sizeof (struct t) == 2 ? 1 : -1];
diff --git a/gcc/testsuite/gcc.dg/bitfld-18.c b/gcc/testsuite/gcc.dg/bitfld-18.c
new file mode 100644 (file)
index 0000000..2cd8e7d
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-Wno-packed-bitfield-compat" } */
+
+struct t
+{
+  char a:4;
+  char b:8 __attribute__ ((packed));
+  char c:4;
+};
+
+int assrt[sizeof (struct t) == 2 ? 1 : -1];