]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/13983 (no warning on some non-POD struct with packed attribute)
authorJason Merrill <jason@gcc.gnu.org>
Thu, 6 Jul 2006 03:33:20 +0000 (23:33 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 6 Jul 2006 03:33:20 +0000 (23:33 -0400)
        PR c++/13983
        PR c++/17519
        * stor-layout.c (finish_record_layout): Copy TYPE_PACKED to variants.
        * cp/class.c (check_field_decls): Check TYPE_PACKED after
        stripping array types.

From-SVN: r115220

gcc/ChangeLog
gcc/cp/ChangeLog
gcc/cp/class.c
gcc/stor-layout.c
gcc/testsuite/g++.dg/ext/packed10.C [new file with mode: 0644]

index e1aeae105526d7e00922d7830ed8bc5974f33294..3a118e4fa763d030dc8c26b0cf63575f127224a0 100644 (file)
@@ -1,3 +1,9 @@
+2006-07-05  Jason Merrill  <jason@redhat.com>
+
+       PR c++/13983
+       PR c++/17519
+       * stor-layout.c (finish_record_layout): Copy TYPE_PACKED to variants.
+
 2006-07-04  Peter O'Gorman  <peter@pogma.com>
 
        * mklibgcc.in: chmod 644 before ranlib during install.
index 4172661926950b370985b729bcc7488d19bc99c9..2c88746868e4f85dc699631965c04728ab196f07 100644 (file)
@@ -1,3 +1,16 @@
+2006-07-05  Jason Merrill  <jason@redhat.com>
+
+       PR c++/13983
+       PR c++/17519
+       * class.c (check_field_decls): Check TYPE_PACKED after
+       stripping array types.
+
+2006-07-05  Nathan Sidwell  <nathan@codesourcery.com>
+
+       PR c++/21166
+       * class.c (check_field_decls): Only set DECL_PACKED on a field
+       when its natural alignment is > BITS_PER_UNIT.
+
 2006-07-05  Jason Merrill  <jason@redhat.com>
 
        PR c++/18681
index 14e8728ca8e96890b793a1679de1821c769c82fe..8066ec9f7fbdb165095a34e7d58f660c320e8d8f 100644 (file)
@@ -2850,39 +2850,6 @@ check_field_decls (tree t, tree *access_decls,
 
       next = &TREE_CHAIN (x);
 
-      if (TREE_CODE (x) == FIELD_DECL)
-       {
-         if (TYPE_PACKED (t))
-           {
-             if (!pod_type_p (TREE_TYPE (x)) && !TYPE_PACKED (TREE_TYPE (x)))
-               cp_warning_at
-                 ("ignoring packed attribute on unpacked non-POD field %q#D",
-                  x);
-             else
-               DECL_PACKED (x) = 1;
-           }
-
-         if (DECL_C_BIT_FIELD (x) && integer_zerop (DECL_INITIAL (x)))
-           /* We don't treat zero-width bitfields as making a class
-              non-empty.  */
-           ;
-         else
-           {
-             tree element_type;
-
-             /* The class is non-empty.  */
-             CLASSTYPE_EMPTY_P (t) = 0;
-             /* The class is not even nearly empty.  */
-             CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
-             /* If one of the data members contains an empty class,
-                so does T.  */
-             element_type = strip_array_types (type);
-             if (CLASS_TYPE_P (element_type) 
-                 && CLASSTYPE_CONTAINS_EMPTY_CLASS_P (element_type))
-               CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 1;
-           }
-       }
-
       if (TREE_CODE (x) == USING_DECL)
        {
          /* Prune the access declaration from the list of fields.  */
@@ -2979,6 +2946,34 @@ check_field_decls (tree t, tree *access_decls,
 
       type = strip_array_types (type);
 
+      if (TYPE_PACKED (t))
+       {
+         if (!pod_type_p (type) && !TYPE_PACKED (type))
+           warning
+             (0,
+              "ignoring packed attribute on unpacked non-POD field %q+#D",
+              x);
+         else if (TYPE_ALIGN (TREE_TYPE (x)) > BITS_PER_UNIT)
+           DECL_PACKED (x) = 1;
+       }
+
+      if (DECL_C_BIT_FIELD (x) && integer_zerop (DECL_INITIAL (x)))
+       /* We don't treat zero-width bitfields as making a class
+          non-empty.  */
+       ;
+      else
+       {
+         /* The class is non-empty.  */
+         CLASSTYPE_EMPTY_P (t) = 0;
+         /* The class is not even nearly empty.  */
+         CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
+         /* If one of the data members contains an empty class,
+            so does T.  */
+         if (CLASS_TYPE_P (type)
+             && CLASSTYPE_CONTAINS_EMPTY_CLASS_P (type))
+           CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 1;
+       }
+
       /* This is used by -Weffc++ (see below). Warn only for pointers
         to members which might hold dynamic memory. So do not warn
         for pointers to functions or pointers to members.  */
index 44aeea826abb99e4db04020ad4f85a5fe172a9e0..78295c5f6f949804760342cc9864d44cf0da9c3b 100644 (file)
@@ -1418,6 +1418,8 @@ finalize_type_size (tree type)
 void
 finish_record_layout (record_layout_info rli, int free_p)
 {
+  tree variant;
+
   /* Compute the final size.  */
   finalize_record_size (rli);
 
@@ -1427,6 +1429,12 @@ finish_record_layout (record_layout_info rli, int free_p)
   /* Perform any last tweaks to the TYPE_SIZE, etc.  */
   finalize_type_size (rli->t);
 
+  /* Propagate TYPE_PACKED to variants.  With C++ templates,
+     handle_packed_attribute is too early to do this.  */
+  for (variant = TYPE_NEXT_VARIANT (rli->t); variant;
+       variant = TYPE_NEXT_VARIANT (variant))
+    TYPE_PACKED (variant) = TYPE_PACKED (rli->t);
+
   /* Lay out any static members.  This is done now because their type
      may use the record's type.  */
   while (rli->pending_statics)
diff --git a/gcc/testsuite/g++.dg/ext/packed10.C b/gcc/testsuite/g++.dg/ext/packed10.C
new file mode 100644 (file)
index 0000000..c4bbb14
--- /dev/null
@@ -0,0 +1,14 @@
+// PR c++/13983, c++/17519
+// The typedef and the array were causing us to miss that A<int> is
+// a packed type.
+
+template <class T>
+struct A {
+  A();
+} __attribute__((packed));
+
+typedef A<int> Ai;
+
+struct B {
+  Ai a[2];
+} __attribute__((packed));