This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ ABI PATCH: Overlong unnamed bitfields


Here's a corner-case patch: unnamed bitfields whose width is longer
than their types on PCC_BITFIELD_TYPE_MATTERS machines.  After my
recent correction to the stor-layout.c PCC_BITFIELD_TYPE_MATTERS
logic, these bitfields were being handled incorrectly.  Fixed with the
following ugliness in the C++ front end.

Tested on i686-pc-linux-gnu, applied on the mainline.

--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com

2003-01-06  Mark Mitchell  <mark@codesourcery.com>

	* class.c (layout_class_type): Correct handling of unnamed
	bitfields wider than their types.

2003-01-06  Mark Mitchell  <mark@codesourcery.com>

	* testsuite/g++.dg/abi/bitfield9.C: New test.

Index: testsuite/g++.dg/abi/bitfield9.C
===================================================================
RCS file: testsuite/g++.dg/abi/bitfield9.C
diff -N testsuite/g++.dg/abi/bitfield9.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/abi/bitfield9.C	7 Jan 2003 01:31:05 -0000
***************
*** 0 ****
--- 1,11 ----
+ // { dg-do run { target i?86-*-* } }
+ // { dg-options -w }
+ 
+ struct X {
+   char : 45;
+ };
+ 
+ int main () {
+   if (__alignof__ (X) != 4)
+     return 1;
+ }
Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.508
diff -c -5 -p -r1.508 class.c
*** cp/class.c	3 Jan 2003 19:48:50 -0000	1.508
--- cp/class.c	7 Jan 2003 01:31:06 -0000
*************** layout_class_type (tree t, tree *virtual
*** 4991,5000 ****
--- 4991,5001 ----
    /* Layout the non-static data members.  */
    for (field = non_static_data_members; field; field = TREE_CHAIN (field))
      {
        tree type;
        tree padding;
+       bool was_unnamed_p = false;
  
        /* We still pass things that aren't non-static data members to
  	 the back-end, in case it wants to do something with them.  */
        if (TREE_CODE (field) != FIELD_DECL)
  	{
*************** layout_class_type (tree t, tree *virtual
*** 5022,5032 ****
        if (DECL_C_BIT_FIELD (field)
  	  && INT_CST_LT (TYPE_SIZE (type), DECL_SIZE (field)))
  	{
  	  integer_type_kind itk;
  	  tree integer_type;
- 
  	  /* We must allocate the bits as if suitably aligned for the
  	     longest integer type that fits in this many bits.  type
  	     of the field.  Then, we are supposed to use the left over
  	     bits as additional padding.  */
  	  for (itk = itk_char; itk != itk_none; ++itk)
--- 5023,5032 ----
*************** layout_class_type (tree t, tree *virtual
*** 5051,5069 ****
--- 5051,5084 ----
  			 "version of GCC", 
  			 t);
  	      padding = size_binop (MINUS_EXPR, DECL_SIZE (field),
  				    TYPE_SIZE (integer_type));
  	    }
+ 	  /* An unnamed bitfield does not normally affect the
+ 	     alignment of the containing class on a target where
+ 	     PCC_BITFIELD_TYPE_MATTERS.  But, the C++ ABI does not
+ 	     make any exceptions for unnamed bitfields when the
+ 	     bitfields are longer than their types.  Therefore, we
+ 	     temporarily give the field a name.  */
+ 	  if (PCC_BITFIELD_TYPE_MATTERS && !DECL_NAME (field))
+ 	    {
+ 	      was_unnamed_p = true;
+ 	      DECL_NAME (field) = make_anon_name ();
+ 	    }
  	  DECL_SIZE (field) = TYPE_SIZE (integer_type);
  	  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);
+       /* If the bit-field had no name originally, remove the name
+ 	 now.  */
+       if (was_unnamed_p)
+ 	DECL_NAME (field) = NULL_TREE;
  
        /* Remember the location of any empty classes in FIELD.  */
        if (abi_version_at_least (2))
  	record_subobject_offsets (TREE_TYPE (field), 
  				  byte_position(field),


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]