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]

PATCH: Fix stor-layout buglet


On the ARM, the G++ bitfield_7 test was failing.  This is a test that
uses a bitfield wider than its type:

  union U {
    int i: 4096;
  };

and then assigns to the bitfield.  

That definition is *approximately* equivalent to:

  union U {
    long long l : 8 * sizeof (long long);
    int : 4096 - 8 * sizeof (long long);
  };

Normally, stor-layout.c will turn a bitfield into an ordinary field if
that field happens to be both (a) the same width as some integer type,
and (b) appropriately aligned.  That didn't happen for the union
above, with the result that the ARM "insv" pattern got used with a
bitfield of width 32.  It doesn't correctly handle such a width, due
to this code:

    HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << width) - 1;

which has undefined behavior.

I think that the manual should indicate what range of bitfield widths
an "insv" pattern must accept, but it does not do so.

Anyhow, in this case, the problem can be fixed by correcting the
problem in stor-layout.c.  The problem is that known_align is set to
zero to mean "the alignment will be as big as you need it to be", but
then there was code that did "known_align >= x", without testing for
zero.

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

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

2003-12-30  Mark Mitchell  <mark@codesourcery.com>

	* stor-layout.c (layout_decl): Turn bitfields into ordinary
	fields, even if they are the first field in a structure.

Index: stor-layout.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/stor-layout.c,v
retrieving revision 1.174
diff -c -5 -p -r1.174 stor-layout.c
*** stor-layout.c	13 Dec 2003 04:11:23 -0000	1.174
--- stor-layout.c	30 Dec 2003 19:40:56 -0000
*************** layout_decl (tree decl, unsigned int kno
*** 433,443 ****
  	      && GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT)
  	    {
  	      enum machine_mode xmode
  		= mode_for_size_tree (DECL_SIZE (decl), MODE_INT, 1);
  
! 	      if (xmode != BLKmode && known_align >= GET_MODE_ALIGNMENT (xmode))
  		{
  		  DECL_ALIGN (decl) = MAX (GET_MODE_ALIGNMENT (xmode),
  					   DECL_ALIGN (decl));
  		  DECL_MODE (decl) = xmode;
  		  DECL_BIT_FIELD (decl) = 0;
--- 433,445 ----
  	      && GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT)
  	    {
  	      enum machine_mode xmode
  		= mode_for_size_tree (DECL_SIZE (decl), MODE_INT, 1);
  
! 	      if (xmode != BLKmode 
! 		  && (known_align == 0
! 		      || known_align >= GET_MODE_ALIGNMENT (xmode)))
  		{
  		  DECL_ALIGN (decl) = MAX (GET_MODE_ALIGNMENT (xmode),
  					   DECL_ALIGN (decl));
  		  DECL_MODE (decl) = xmode;
  		  DECL_BIT_FIELD (decl) = 0;


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