Fixing bitfield union initialization bug.

Vladimir N. Makarov vmakarov@cygnus.com
Mon Feb 8 16:08:00 GMT 1999


Gcc generates the following code for union initialization

union {
   int i:1;
} u = {1};


.long 1
.zero 3

instead of 

.byte 1
.zero 3

Gcc uses two algorithms for initialization.  The first one is
incremental initialization.  Gcc uses the code for incremental filling
union independently from is the first member a bitfield or not.  This
code ignores bitfiled flags and the bitfield in the example is
considered to be simply int.  The second algorithm is used for filling
structure with bitfields.  So to solve the problem, the second
algorithm code could be used for initialization of union whose the
first member is a bitfield.


Here the patch for egcs for solving the problem is.

Vladimir Makarov


Mon Feb  9 18:57:45 1999  Vladimir N. Makarov  <vmakarov@cygnus.com>

	* c-typeck.c (check_init_type_bitfields): Use nonincremental
	initialization of unions whose first member is a bitfield.
        Remove unnecessary code for checking the declaration mode
        after DECL_C_BIT_FIELD.

	* varasm.c (output_constructor): Additional comment about the
 	constructor of bitfield union initialization.

Index: c-typeck.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/c-typeck.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -p -r1.23 -r1.24
*** c-typeck.c	1999/01/27 01:41:49	1.23
--- c-typeck.c	1999/02/08 16:00:45	1.24
*************** check_init_type_bitfields (type)
*** 5480,5488 ****
        for (tail = TYPE_FIELDS (type); tail;
  	   tail = TREE_CHAIN (tail))
  	{
! 	  if (DECL_C_BIT_FIELD (tail)
! 	      /* This catches cases like `int foo : 8;'.  */
! 	      || DECL_MODE (tail) != TYPE_MODE (TREE_TYPE (tail)))
  	    {
  	      constructor_incremental = 0;
  	      break;
--- 5480,5486 ----
        for (tail = TYPE_FIELDS (type); tail;
  	   tail = TREE_CHAIN (tail))
  	{
! 	  if (DECL_C_BIT_FIELD (tail))
  	    {
  	      constructor_incremental = 0;
  	      break;
*************** check_init_type_bitfields (type)
*** 5490,5495 ****
--- 5488,5504 ----
  
  	  check_init_type_bitfields (TREE_TYPE (tail));
  	}
+     }
+ 
+   else if (TREE_CODE (type) == UNION_TYPE)
+     {
+       tree tail = TYPE_FIELDS (type);
+       if (tail && DECL_C_BIT_FIELD (tail))
+ 	/* We also use the nonincremental algorithm for initiliazation
+ 	   of unions whose first member is a bitfield, becuase the
+ 	   incremental algorithm has no code for dealing with
+ 	   bitfields. */
+ 	constructor_incremental = 0;
      }
  
    else if (TREE_CODE (type) == ARRAY_TYPE)
Index: varasm.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/varasm.c,v
retrieving revision 1.52
retrieving revision 1.53
diff -p -r1.52 -r1.53
*** varasm.c	1999/01/27 01:42:51	1.52
--- varasm.c	1999/02/08 16:00:46	1.53
*************** output_constructor (exp, size)
*** 3998,4004 ****
       FIELD goes through the structure fields, if the constant is a structure.
       if the constant is a union, then we override this,
       by getting the field from the TREE_LIST element.
!      But the constant could also be an array.  Then FIELD is zero.  */
    for (link = CONSTRUCTOR_ELTS (exp);
         link;
         link = TREE_CHAIN (link),
--- 3998,4008 ----
       FIELD goes through the structure fields, if the constant is a structure.
       if the constant is a union, then we override this,
       by getting the field from the TREE_LIST element.
!      But the constant could also be an array.  Then FIELD is zero.
! 
!      There is always a maximum of one element in the chain LINK for unions
!      (even if the initializer in a source program incorrectly contains
!      more one). */
    for (link = CONSTRUCTOR_ELTS (exp);
         link;
         link = TREE_CHAIN (link),


More information about the Gcc-patches mailing list