]> 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@redhat.com>
Thu, 6 Jul 2006 02:09:02 +0000 (22:09 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 6 Jul 2006 02:09:02 +0000 (22:09 -0400)
        PR c++/13983
        PR c++/17519
        * stor-layout.c (finish_record_layout): Copy TYPE_PACKED to variants.
        * c-common.c (handle_packed_attribute): So don't copy it here.
        * c-decl.c (finish_struct): Don't copy TYPE_ALIGN.
        * cp/class.c (check_field_decls): Check TYPE_PACKED after
        stripping array types.
        (finish_struct_bits): Don't copy TYPE_SIZE here.

From-SVN: r115217

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

index 6a4d377bd4f30903f8ba4ea806ec348aefbf1543..fc4194d18e2126f922f32e1230d616284dfff08d 100644 (file)
@@ -1,3 +1,11 @@
+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.
+       * c-common.c (handle_packed_attribute): So don't copy it here.
+       * c-decl.c (finish_struct): Don't copy TYPE_ALIGN.
+
 2006-07-05  Mike Stump  <mrs@apple.com>
 
        * doc/invoke.texi (Invoking G++): Clarify prose for g++.
index ac7dd7ddee3de4c4257153e7e88f1475ff52facc..61bf12bbb59df8feedf64cc73445bd7adeb3e314 100644 (file)
@@ -4082,20 +4082,6 @@ handle_packed_attribute (tree *node, tree name, tree ARG_UNUSED (args),
       if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
        *node = build_variant_type_copy (*node);
       TYPE_PACKED (*node) = 1;
-      if (TYPE_MAIN_VARIANT (*node) == *node)
-       {
-         /* If it is the main variant, then pack the other variants
-            too. This happens in,
-
-            struct Foo {
-              struct Foo const *ptr; // creates a variant w/o packed flag
-            } __ attribute__((packed)); // packs it now.
-          */
-         tree probe;
-
-         for (probe = *node; probe; probe = TYPE_NEXT_VARIANT (probe))
-           TYPE_PACKED (probe) = 1;
-       }
     }
   else if (TREE_CODE (*node) == FIELD_DECL)
     {
index 250be0e055dbba224409effb44d2fad3fc0926ff..6ad6a695d08964e071d5c3d35a26061dc235b6da 100644 (file)
@@ -5574,8 +5574,6 @@ finish_struct (tree t, tree fieldlist, tree attributes)
     {
       TYPE_FIELDS (x) = TYPE_FIELDS (t);
       TYPE_LANG_SPECIFIC (x) = TYPE_LANG_SPECIFIC (t);
-      TYPE_ALIGN (x) = TYPE_ALIGN (t);
-      TYPE_USER_ALIGN (x) = TYPE_USER_ALIGN (t);
       C_TYPE_FIELDS_READONLY (x) = C_TYPE_FIELDS_READONLY (t);
       C_TYPE_FIELDS_VOLATILE (x) = C_TYPE_FIELDS_VOLATILE (t);
       C_TYPE_VARIABLE_SIZE (x) = C_TYPE_VARIABLE_SIZE (t);
index b1a1cbd1459ddc99dae9fb63b0a75c0a1d4c85c0..3d3952cb681bd088b51cc7f41c9db2d20f418352 100644 (file)
@@ -1,5 +1,11 @@
 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.
+       (finish_struct_bits): Don't copy TYPE_SIZE here.
+
        PR c++/18681
        * friend.c (is_friend): Fix DR 45 implementation.
 
index 9761c5c41a7d55db1ab8607747686e2d7f570ce1..06f8cbceb53330d94a0fdbaf71b890bf500d1eee 100644 (file)
@@ -1433,8 +1433,6 @@ finish_struct_bits (tree t)
       TYPE_VFIELD (variants) = TYPE_VFIELD (t);
       TYPE_METHODS (variants) = TYPE_METHODS (t);
       TYPE_FIELDS (variants) = TYPE_FIELDS (t);
-      TYPE_SIZE (variants) = TYPE_SIZE (t);
-      TYPE_SIZE_UNIT (variants) = TYPE_SIZE_UNIT (t);
     }
 
   if (BINFO_N_BASE_BINFOS (TYPE_BINFO (t)) && TYPE_POLYMORPHIC_P (t))
@@ -2815,40 +2813,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)))
-               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
-           {
-             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.  */
@@ -2945,6 +2909,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 47bc6a047a73ef357acb233d9a86788e44301e5a..76aa4ac73bbf024aee4ed8aa1c3d00a65023a4c3 100644 (file)
@@ -1465,6 +1465,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);
 
@@ -1474,6 +1476,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));