Incorrect initialisation of SRA bitfield blocks

Richard Sandiford rsandifo@nildram.co.uk
Sat Dec 29 15:20:00 GMT 2007


g++.dg/opt/nrv4.C is failing for MIPS n32 because SRA does zero
initialisation _after_ non-default initialisation.  The two may
overlap when using bitfield blocks, so the former should be done first.

Specifically, we have:

struct GdkColor {
  long  pixel;
  short red;
  short green;
  short blue;
};
...
  GdkColor ret={0,1,2,3};

and SRA decides to use a single bitfield block for ret.{red,green}.
generate_element_init copies { 0, 1, 2, 3 } to the appropriate
scalarised elements, setting the visited flag for each one.  However,
the parent element that represents the ret.{red,green} bitfield block
does not have its visited flag set; only the individual ret.red and
ret.green elements do.  generate_element_zero therefore zero-initialises
the block, overwriting the earlier values.

Bootstrapped & regression-tested on x86_64-linux-gnu and
regression-tested on mips64-linux-gnu.  OK to install?

Richard


gcc/
	* tree-sra.c (scalarize_init): Insert the generate_element_init
	statements after the generate_element_zero statements.

Index: gcc/tree-sra.c
===================================================================
--- gcc/tree-sra.c	2007-12-28 21:03:58.000000000 +0000
+++ gcc/tree-sra.c	2007-12-28 21:11:12.000000000 +0000
@@ -3354,19 +3354,20 @@ scalarize_copy (struct sra_elt *lhs_elt,
 scalarize_init (struct sra_elt *lhs_elt, tree rhs, block_stmt_iterator *bsi)
 {
   bool result = true;
-  tree list = NULL;
+  tree list = NULL, init_list = NULL;
 
   /* Generate initialization statements for all members extant in the RHS.  */
   if (rhs)
     {
       /* Unshare the expression just in case this is from a decl's initial.  */
       rhs = unshare_expr (rhs);
-      result = generate_element_init (lhs_elt, rhs, &list);
+      result = generate_element_init (lhs_elt, rhs, &init_list);
     }
 
   /* CONSTRUCTOR is defined such that any member not mentioned is assigned
      a zero value.  Initialize the rest of the instantiated elements.  */
   generate_element_zero (lhs_elt, &list);
+  append_to_statement_list (init_list, &list);
 
   if (!result)
     {



More information about the Gcc-patches mailing list