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++ PATCH: Fix PR c++/10549


This patch fixes an obscure regression involving the use of bitfields
whose width is wider than that of their declared type.

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

--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com

2003-04-29  Mark Mitchell  <mark@codesourcery.com>

	PR c++/10549
	* class.c (layout_class_type): Mark overlong bitfields as having
	the maximum size permitted by their type, after layout.

2003-04-29  Mark Mitchell  <mark@codesourcery.com>

	PR c++/10549
	* g++.dg/other/bitfield1.C: New test.

Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.534
diff -c -5 -p -r1.534 class.c
*** cp/class.c	28 Apr 2003 06:06:58 -0000	1.534
--- cp/class.c	29 Apr 2003 21:24:54 -0000
*************** layout_class_type (tree t, tree *virtual
*** 4722,4732 ****
    /* 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)
  	{
--- 4722,4731 ----
*************** layout_class_type (tree t, tree *virtual
*** 4756,4765 ****
--- 4755,4765 ----
        if (DECL_C_BIT_FIELD (field)
  	  && INT_CST_LT (TYPE_SIZE (type), DECL_SIZE (field)))
  	{
  	  integer_type_kind itk;
  	  tree integer_type;
+ 	  bool was_unnamed_p = false;
  	  /* 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)
*************** layout_class_type (tree t, tree *virtual
*** 4807,4824 ****
  	    }
  #endif
  	  DECL_SIZE (field) = TYPE_SIZE (integer_type);
  	  DECL_ALIGN (field) = TYPE_ALIGN (integer_type);
  	  DECL_USER_ALIGN (field) = TYPE_USER_ALIGN (integer_type);
  	}
! 
!       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),
--- 4807,4828 ----
  	    }
  #endif
  	  DECL_SIZE (field) = TYPE_SIZE (integer_type);
  	  DECL_ALIGN (field) = TYPE_ALIGN (integer_type);
  	  DECL_USER_ALIGN (field) = TYPE_USER_ALIGN (integer_type);
+ 	  layout_nonempty_base_or_field (rli, field, NULL_TREE,
+ 					 empty_base_offsets);
+ 	  if (was_unnamed_p)
+ 	    DECL_NAME (field) = NULL_TREE;
+ 	  /* Now that layout has been performed, set the size of the
+ 	     field to the size of its declared type; the rest of the
+ 	     field is effectively invisible.  */
+ 	  DECL_SIZE (field) = TYPE_SIZE (type);
  	}
!       else
! 	layout_nonempty_base_or_field (rli, field, NULL_TREE,
! 				       empty_base_offsets);
  
        /* 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: testsuite/g++.dg/other/bitfield1.C
===================================================================
RCS file: testsuite/g++.dg/other/bitfield1.C
diff -N testsuite/g++.dg/other/bitfield1.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/other/bitfield1.C	29 Apr 2003 21:24:57 -0000
***************
*** 0 ****
--- 1,9 ----
+ // { dg-options "-w" }
+ 
+ union u1 {
+   char m1 : 16;
+ } x;
+ 
+ int main () {
+   x.m1 = 256;
+ }


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