class.c (layout_class_type): Correct handling for overlong bit-fields whose width...
authorMark Mitchell <mark@codesourcery.com>
Thu, 10 Apr 2003 19:28:46 +0000 (19:28 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Thu, 10 Apr 2003 19:28:46 +0000 (19:28 +0000)
* class.c (layout_class_type): Correct handling for overlong
bit-fields whose width is the same as an integer type.

* g++.dg/abi/bitfield10.C: New test.

From-SVN: r65432

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/abi/bitfield10.C [new file with mode: 0644]

index 8311500c56ba6a906f1d3cc5e9217f94415dacd0..3e3e4f3d73cbfd62ce3043097c87597de5f1be34 100644 (file)
@@ -1,3 +1,8 @@
+2003-04-10  Mark Mitchell  <mark@codesourcery.com>
+
+       * class.c (layout_class_type): Correct handling for overlong
+       bit-fields whose width is the same as an integer type.
+
 2003-04-06  Zack Weinberg   <zack@codesourcery.com>
 
        * cp-tree.def: Make fourth element for all 'c' and 'x' nodes zero.
index e6fad0a11434eca6887f422263e5b0f3fb76d4a8..ed0824a1c0e87b811230d5d057604fef3a434b82 100644 (file)
@@ -4819,6 +4819,8 @@ layout_class_type (tree t, tree *virtuals_p)
        }
 
       type = TREE_TYPE (field);
+      
+      padding = NULL_TREE;
 
       /* If this field is a bit-field whose width is greater than its
         type, then there are some special rules for allocating
@@ -4842,19 +4844,26 @@ layout_class_type (tree t, tree *virtuals_p)
             type that fits.  */
          integer_type = integer_types[itk - 1];
 
-         if (abi_version_at_least (2) && TREE_CODE (t) == UNION_TYPE)
-           /* In a union, the padding field must have the full width
-              of the bit-field; all fields start at offset zero.  */
-           padding = DECL_SIZE (field);
-         else
+         /* Figure out how much additional padding is required.  GCC
+            3.2 always created a padding field, even if it had zero
+            width.  */
+         if (!abi_version_at_least (2)
+             || INT_CST_LT (TYPE_SIZE (integer_type), DECL_SIZE (field)))
            {
-             if (warn_abi && TREE_CODE (t) == UNION_TYPE)
-               warning ("size assigned to `%T' may not be "
-                        "ABI-compliant and may change in a future "
-                        "version of GCC", 
-                        t);
-             padding = size_binop (MINUS_EXPR, DECL_SIZE (field),
-                                   TYPE_SIZE (integer_type));
+             if (abi_version_at_least (2) && TREE_CODE (t) == UNION_TYPE)
+               /* In a union, the padding field must have the full width
+                  of the bit-field; all fields start at offset zero.  */
+               padding = DECL_SIZE (field);
+             else
+               {
+                 if (warn_abi && TREE_CODE (t) == UNION_TYPE)
+                   warning ("size assigned to `%T' may not be "
+                            "ABI-compliant and may change in a future "
+                            "version of GCC", 
+                            t);
+                 padding = size_binop (MINUS_EXPR, DECL_SIZE (field),
+                                       TYPE_SIZE (integer_type));
+               }
            }
 #ifdef PCC_BITFIELD_TYPE_MATTERS
          /* An unnamed bitfield does not normally affect the
@@ -4873,8 +4882,6 @@ layout_class_type (tree t, tree *virtuals_p)
          DECL_ALIGN (field) = TYPE_ALIGN (integer_type);
          DECL_USER_ALIGN (field) = TYPE_USER_ALIGN (integer_type);
        }
-      else
-       padding = NULL_TREE;
 
       layout_nonempty_base_or_field (rli, field, NULL_TREE,
                                     empty_base_offsets);
@@ -4924,6 +4931,7 @@ layout_class_type (tree t, tree *virtuals_p)
                                      char_type_node); 
          DECL_BIT_FIELD (padding_field) = 1;
          DECL_SIZE (padding_field) = padding;
+         DECL_CONTEXT (padding_field) = t;
          layout_nonempty_base_or_field (rli, padding_field,
                                         NULL_TREE, 
                                         empty_base_offsets);
index dfddab2834cc64159c8fd7792a7d1eed50d17b85..52be21cb002692cefa23884e9982903d742b8c92 100644 (file)
@@ -1,3 +1,7 @@
+2003-04-10  Mark Mitchell  <mark@codesourcery.com>
+
+       * g++.dg/abi/bitfield10.C: New test.
+
 2003-04-09  Mike Stump  <mrs@apple.com>
 
        * gcc.dg/pch/pch.exp: Make testcase names longer.
diff --git a/gcc/testsuite/g++.dg/abi/bitfield10.C b/gcc/testsuite/g++.dg/abi/bitfield10.C
new file mode 100644 (file)
index 0000000..df40fa3
--- /dev/null
@@ -0,0 +1,5 @@
+// { dg-options "-w" }
+
+struct S {
+  int i : 64;
+};