2005-07-02  Giovanni Bajo  <giovannibajo@libero.it>

	Make CONSTRUCTOR use VEC to store initializers.
	* c-common.c (complete_array_type): Update to cope with VEC in
	CONSTRUCTOR_ELTS.
	* c-pretty-print.c (pp_c_initializer_list): Use pp_c_constructor_elts.
	(pp_c_constructor_elts): New function.
	* c-pretty-print.h (pp_c_constructor_elts): Declare.
	* c-typeck.c (build_function_call, build_c_cast, digest_init,
	struct constructor_stack, struct initializer_stack,
	constructor_elements, push_init_level, pop_init_level, add_pending_init,
	find_init_member, output_init_element): Update to cope with VEC in
	CONSTRUCTOR_ELTS.
	* coverage.c (build_fn_info_value, build_ctr_info_value,
	build_gcov_info): Likewise.
	* expr.c (categorize_ctor_elements_1, store_constructor,
	expand_expr_real_1): Likewise.
	* fold-const.c (fold_ternary): Likewise.
	* gimplify.c (gimplify_init_ctor_preeval, zero_sized_field_decl,
	gimplify_init_constructor, gimplify_expr): Likewise.
	* tree-dump.c (dequeue_and_dump): Likewise.
	* tree-inline.c (copy_tree_r): Add code to duplicate a CONSTRUCTOR
	node.
	* tree-pretty-print.c (dump_generic_node): Update to cope with VEC in
	CONSTRUCTOR_ELTS.
	* tree-sra.c (generate_element_init_1): Likewise.
	* tree-ssa-ccp.c (fold_const_aggregate_ref): Likewise.
	* tree-ssa-operands.c (get_expr_operands): Likewise.
	* tree-vect-generic.c (expand_vector_piecewise): Likewise.
	* tree-vect-transform.c (vect_get_vec_def_for_operand):
	(get_initial_def_for_reduction): Likewise.
	* tree-vn.c (set_value_handle, get_value_handle): CONSTURCTOR uses
	value handle in annotations.
	* tree.c (tree_node_kind, tree_code_size, make_node_stat,
	tree_node_structure): Add support for constr_kind.
	(build_vector_from_ctor, build_constructor_single,
	build_constructor_from_list): New functions.
	(build_constructor): Update to take a VEC instead of a TREE_LIST.
	(simple_cst_equal, iterative_hash_expr, initializer_zerop, walk_tree):
	Update to cope with VEC in CONSTRUCTOR_ELTS.
	* tree.def (CONSTRUCTOR): Make it a tcc_exceptional node.
	* tree.h (FOR_EACH_CONSTRUCTOR_VALUE, FOR_EACH_CONSTRUCTOR_ELT,
	CONSTRUCTOR_APPEND_ELT): New macros.
	(struct constructor_elt, struct	tree_constructor): New data types.
	(union tree_node): Add tree_constructor field.
	* treestruct.def: Define TS_CONSTRUCTOR.
	* varasm.c (const_hash_1, compare_constant, copy_constant,
	compute_reloc_for_constant, output_addressed_constants,
	initializer_constant_valid_p, output_constant,
	array_size_for_constructor, output_constructor): Update to cope with
	VEC in CONSTRUCTOR_ELTS.
	* vec.h (VEC_empty, VEC_copy): New macros.
	
ada/
	Make CONSTRUCTOR use VEC to store initializers.
	* decl.c (gnat_to_gnu_entity): Update to cope with VEC in
	CONSTRUCTOR_ELTS.
	* trans.c (extract_values): Likewise.
	* utils.c (convert, remove_conversions): Likewise.
	* utils2.c (contains_save_expr_p, build_binary_op, build_unary_op,
	gnat_build_constructor): Likewise.
	
cp/
	Make CONSTRUCTOR use VEC to store initializers.
	* call.c (convert_default_arg): Update call to digest_init.
	* class.c (dump_class_hierarchy, dump_array): Update to cope with VEC
	in CONSTRUCTOR_ELTS.
	* cp-tree.h (EMPTY_CONSTRUCTOR_P): Likewise.
	(finish_compound_literal, digest_init): Update declaration.
	* decl.c (struct reshape_iter): New data type.
	(reshape_init_array): Rename to...
	(reshape_init_array_1): Update to cope with VEC in CONSTRUCTOR_ELTS.
	(reshape_init): Rewrite from scratch. Split parts into...
	(reshape_init_array, reshape_init_vector, reshape_init_class,
	reshape_init_r): New functions.
	(check_initializer): Update call to reshape_init. Remove obsolete code.
	(initialize_artificial_var, cp_complete_array_type): Update to cope
	with VEC in CONSTRUCTOR_ELTS.
	* decl2.c (grokfield): Update calls to digest_init.
	(mark_vtable_entries): Update to cope with VEC in CONSTRUCTOR_ELTS.
	* error.c (dump_expr_init_vec): New function.
	(dump_expr): Use dump_expr_init_vec.
	* init.c (build_zero_init, build_vec_init): Update to cope with VEC in
	CONSTRUCTOR_ELTS.
	(expand_default_init): Update call to digest_init.
	* parser.c  (cp_parser_postfix_expression): Use a VEC for the
	initializers.
	(cp_parser_initializer_list): Build a VEC of initializers.
	* pt.c (tsubst_copy, tsubst_copy_and_build): Update to cope with VEC in
	CONSTRUCTOR_ELTS.
	* rtti.c (tinfo_base_init, generic_initializer, ptr_initializer,
	ptm_initializer, class_initializer, get_pseudo_ti_init): Use
	build_constructor_from_list instead of build_constructor.
	* semantics.c (finish_compound_literal): Update call to digest_init.
	* tree.c (stabilize_init): Update to cope with VEC in CONSTRUCTOR_ELTS.
	* typeck.c (build_ptrmemfunc1): Likewise.
	* typeck2.c: (cxx_incomplete_type_error, split_nonconstant_init_1):
	Likewise.
	(store_init_value): Use build_constructor_from_list and update call to
	digest_init.
	(digest_init): Rewrite.
	(process_init_constructor): Rewrite from scratch. Split into...
	(process_init_constructor_array, picflag_from_initializer,
	process_init_constructor_record, process_init_constructor_union): New
	functions.
	(PICFLAG_ERRONEOUS, PICFLAG_NOT_ALL_CONSTANT, PICFLAG_NOT_ALL_SIMPLE):
	New macros.
	(build_functional_cast): Use build_constructor_from_list instead of
	build_constructor.


fortran/
	Make CONSTRUCTOR use VEC to store initializers.
	* trans-array.c (gfc_build_null_descriptor,
	gfc_trans_array_constructor_value, gfc_conv_array_initializer):
	Update to cope with VEC in CONSTRUCTOR_ELTS.
	* trans-common.c (create_common): Likewise.
	* trans-expr.c (gfc_conv_structure): Likewise.
	* trans-stmt.c (gfc_trans_character_select): Use
	build_constructor_from_list instead of build_constructor.
	
java/
	Make CONSTRUCTOR use VEC to store initializers.
	* check-init.c (check_init): Update to cope with VEC in
	CONSTRUCTOR_ELTS.
	* class.c (make_field_value, make_method_value, get_dispatch_table,
	make_class_data, emit_symbol_table, emit_catch_table,
	emit_assertion_table): Use build_constructor_from_list instead of
	build_constructor.
	* constants.c (build_constants_constructor): Likewise.
	* java-gimplify.c (java_gimplify_new_array_init): Update to cope with
	VEC in CONSTRUCTOR_ELTS.
	* java-tree.h (START_RECORD_CONSTRUCTOR, PUSH_SUPER_VALUE,
	PUSH_FIELD_VALUE, FINISH_RECORD_CONSTRUCTOR): Create a VEC instead
	of a TREE_LIST.
	* jcf-write.c (generate_bytecode_insns): Update to cope with VEC in
	CONSTRUCTOR_ELTS.
	* parse.y (build_new_array_init): Use build_constructor_from_list
	instead of build_constructor.
	(patch_new_array_init): Update to cope with VEC in
	CONSTRUCTOR_ELTS.
	(array_constructor_check_entry): Likewise.
	
objc/
	Make CONSTRUCTOR use VEC to store initializers.
	* objc-act.c (objc_build_constructor): Use build_constructor_from_list
	instead of build_constructor.
	
testsuite/
	Make CONSTRUCTOR use VEC to store initializers.
	* g++.dg/ext/complit3.C: Check for specific error messages.
	* g++.dg/init/brace2.C: Update error message.
	* g++.dg/warn/Wbraces2.C: Likewise.

? local.diff
? patch-constr.txt
? path-constr.txt
? vec-copy.patch
? cp/cp-tree.
? testsuite/g++.torture
? testsuite/g++.dg/ext/attrib16.C
? testsuite/g++.dg/ext/attrib17.C
? testsuite/g++.dg/tc1/dr49.C
? testsuite/g++.dg/template/array11.C
? testsuite/g++.dg/template/mem_func_ptr.C
? testsuite/g++.dg/template/nontype10.C
? testsuite/g++.dg/template/nontype7.C
? testsuite/g++.dg/template/nontype8.C
? testsuite/g++.dg/template/nontype9.C
Index: c-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.c,v
retrieving revision 1.643
diff -c -p -r1.643 c-common.c
*** c-common.c	2 Jul 2005 10:54:02 -0000	1.643
--- c-common.c	9 Jul 2005 15:24:16 -0000
*************** complete_array_type (tree *ptype, tree i
*** 5913,5921 ****
  	}
        else if (TREE_CODE (initial_value) == CONSTRUCTOR)
  	{
! 	  tree elts = CONSTRUCTOR_ELTS (initial_value);
  
! 	  if (elts == NULL)
  	    {
  	      if (pedantic)
  		failure = 3;
--- 5913,5921 ----
  	}
        else if (TREE_CODE (initial_value) == CONSTRUCTOR)
  	{
! 	  VEC(constructor_elt,gc) *v = CONSTRUCTOR_ELTS (initial_value);
  
! 	  if (VEC_empty (constructor_elt, v))
  	    {
  	      if (pedantic)
  		failure = 3;
*************** complete_array_type (tree *ptype, tree i
*** 5924,5938 ****
  	  else
  	    {
  	      tree curindex;
  
! 	      if (TREE_PURPOSE (elts))
! 		maxindex = fold_convert (sizetype, TREE_PURPOSE (elts));
  	      curindex = maxindex;
  
! 	      for (elts = TREE_CHAIN (elts); elts; elts = TREE_CHAIN (elts))
  		{
! 		  if (TREE_PURPOSE (elts))
! 		    curindex = fold_convert (sizetype, TREE_PURPOSE (elts));
  		  else
  		    curindex = size_binop (PLUS_EXPR, curindex, size_one_node);
  
--- 5924,5944 ----
  	  else
  	    {
  	      tree curindex;
+ 	      unsigned HOST_WIDE_INT cnt;
+ 	      constructor_elt *ce;
  
! 	      if (VEC_index (constructor_elt, v, 0)->index)
! 		maxindex = fold_convert (sizetype,
! 					 VEC_index (constructor_elt,
! 						    v, 0)->index);
  	      curindex = maxindex;
  
! 	      for (cnt = 1;
! 		   VEC_iterate (constructor_elt, v, cnt, ce);
! 		   cnt++)
  		{
! 		  if (ce->index)
! 		    curindex = fold_convert (sizetype, ce->index);
  		  else
  		    curindex = size_binop (PLUS_EXPR, curindex, size_one_node);
  
Index: c-pretty-print.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-pretty-print.c,v
retrieving revision 1.64
diff -c -p -r1.64 c-pretty-print.c
*** c-pretty-print.c	25 Jun 2005 01:59:23 -0000	1.64
--- c-pretty-print.c	9 Jul 2005 15:24:16 -0000
*************** pp_c_initializer_list (c_pretty_printer 
*** 1126,1139 ****
        if (TREE_CODE (e) == VECTOR_CST)
          pp_c_expression_list (pp, TREE_VECTOR_CST_ELTS (e));
        else if (TREE_CODE (e) == CONSTRUCTOR)
!         pp_c_expression_list (pp, CONSTRUCTOR_ELTS (e));
        else
          break;
        return;
  
      case COMPLEX_TYPE:
        if (TREE_CODE (e) == CONSTRUCTOR)
! 	pp_c_expression_list (pp, CONSTRUCTOR_ELTS (e));
        else if (TREE_CODE (e) == COMPLEX_CST || TREE_CODE (e) == COMPLEX_EXPR)
  	{
  	  const bool cst = TREE_CODE (e) == COMPLEX_CST;
--- 1126,1139 ----
        if (TREE_CODE (e) == VECTOR_CST)
          pp_c_expression_list (pp, TREE_VECTOR_CST_ELTS (e));
        else if (TREE_CODE (e) == CONSTRUCTOR)
!         pp_c_constructor_elts (pp, CONSTRUCTOR_ELTS (e));
        else
          break;
        return;
  
      case COMPLEX_TYPE:
        if (TREE_CODE (e) == CONSTRUCTOR)
! 	pp_c_constructor_elts (pp, CONSTRUCTOR_ELTS (e));
        else if (TREE_CODE (e) == COMPLEX_CST || TREE_CODE (e) == COMPLEX_EXPR)
  	{
  	  const bool cst = TREE_CODE (e) == COMPLEX_CST;
*************** pp_c_expression_list (c_pretty_printer *
*** 1358,1363 ****
--- 1358,1379 ----
      }
  }
  
+ /* Print out V, which contains the elements of a constructor.  */
+ 
+ void
+ pp_c_constructor_elts (c_pretty_printer *pp, VEC(constructor_elt,gc) *v)
+ {
+   unsigned HOST_WIDE_INT ix;
+   tree value;
+ 
+   FOR_EACH_CONSTRUCTOR_VALUE (v, ix, value)
+     {
+       pp_expression (pp, value);
+       if (ix != VEC_length (constructor_elt, v) - 1)
+ 	pp_separate_with (pp, ',');
+     }
+ }
+ 
  /* Print out an expression-list in parens, as in a function call.  */
  
  void
Index: c-pretty-print.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-pretty-print.h,v
retrieving revision 1.18
diff -c -p -r1.18 c-pretty-print.h
*** c-pretty-print.h	25 Jun 2005 01:59:23 -0000	1.18
--- c-pretty-print.h	9 Jul 2005 15:24:16 -0000
*************** void pp_c_statement (c_pretty_printer *,
*** 192,197 ****
--- 192,198 ----
  void pp_c_expression (c_pretty_printer *, tree);
  void pp_c_logical_or_expression (c_pretty_printer *, tree);
  void pp_c_expression_list (c_pretty_printer *, tree);
+ void pp_c_constructor_elts (c_pretty_printer *, VEC(constructor_elt,gc) *);
  void pp_c_call_argument_list (c_pretty_printer *, tree);
  void pp_c_unary_expression (c_pretty_printer *, tree);
  void pp_c_cast_expression (c_pretty_printer *, tree);
Index: c-typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-typeck.c,v
retrieving revision 1.464
diff -c -p -r1.464 c-typeck.c
*** c-typeck.c	5 Jul 2005 17:50:03 -0000	1.464
--- c-typeck.c	9 Jul 2005 15:24:18 -0000
*************** build_function_call (tree function, tree
*** 2061,2068 ****
  
  	  if (AGGREGATE_TYPE_P (return_type))
  	    rhs = build_compound_literal (return_type,
! 					  build_constructor (return_type,
! 							     NULL_TREE));
  	  else
  	    rhs = fold_build1 (NOP_EXPR, return_type, integer_zero_node);
  
--- 2061,2067 ----
  
  	  if (AGGREGATE_TYPE_P (return_type))
  	    rhs = build_compound_literal (return_type,
! 					  build_constructor (return_type, 0));
  	  else
  	    rhs = fold_build1 (NOP_EXPR, return_type, integer_zero_node);
  
*************** build_c_cast (tree type, tree expr)
*** 3210,3217 ****
  	  if (pedantic)
  	    pedwarn ("ISO C forbids casts to union type");
  	  t = digest_init (type,
! 			   build_constructor (type,
! 					      build_tree_list (field, value)),
  			   true, 0);
  	  TREE_CONSTANT (t) = TREE_CONSTANT (value);
  	  TREE_INVARIANT (t) = TREE_INVARIANT (value);
--- 3209,3215 ----
  	  if (pedantic)
  	    pedwarn ("ISO C forbids casts to union type");
  	  t = digest_init (type,
! 			   build_constructor_single (type, field, value),
  			   true, 0);
  	  TREE_CONSTANT (t) = TREE_CONSTANT (value);
  	  TREE_INVARIANT (t) = TREE_INVARIANT (value);
*************** digest_init (tree type, tree init, bool 
*** 4348,4365 ****
  
        if (TREE_CODE (inside_init) == CONSTRUCTOR)
  	{
! 	  tree link;
  
  	  /* Iterate through elements and check if all constructor
  	     elements are *_CSTs.  */
! 	  for (link = CONSTRUCTOR_ELTS (inside_init);
! 	       link;
! 	       link = TREE_CHAIN (link))
! 	    if (! CONSTANT_CLASS_P (TREE_VALUE (link)))
! 	      break;
  
! 	  if (link == NULL)
! 	    return build_vector (type, CONSTRUCTOR_ELTS (inside_init));
  	}
      }
  
--- 4346,4367 ----
  
        if (TREE_CODE (inside_init) == CONSTRUCTOR)
  	{
! 	  unsigned HOST_WIDE_INT ix;
! 	  tree value;
! 	  bool constant_p = true;
  
  	  /* Iterate through elements and check if all constructor
  	     elements are *_CSTs.  */
! 	  FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (inside_init), ix, value)
! 	    if (!CONSTANT_CLASS_P (value))
! 	      {
! 		constant_p = false;
! 		break;
! 	      }
  
! 	  if (constant_p)
! 	    return build_vector_from_ctor (type,
! 					   CONSTRUCTOR_ELTS (inside_init));
  	}
      }
  
*************** static tree constructor_bit_index;
*** 4521,4527 ****
  /* If we are saving up the elements rather than allocating them,
     this is the list of elements so far (in reverse order,
     most recent first).  */
! static tree constructor_elements;
  
  /* 1 if constructor should be incrementally stored into a constructor chain,
     0 if all the elements should be kept in AVL tree.  */
--- 4523,4529 ----
  /* If we are saving up the elements rather than allocating them,
     this is the list of elements so far (in reverse order,
     most recent first).  */
! static VEC(constructor_elt,gc) *constructor_elements;
  
  /* 1 if constructor should be incrementally stored into a constructor chain,
     0 if all the elements should be kept in AVL tree.  */
*************** struct constructor_stack
*** 4592,4598 ****
    tree unfilled_index;
    tree unfilled_fields;
    tree bit_index;
!   tree elements;
    struct init_node *pending_elts;
    int offset;
    int depth;
--- 4594,4600 ----
    tree unfilled_index;
    tree unfilled_fields;
    tree bit_index;
!   VEC(constructor_elt,gc) *elements;
    struct init_node *pending_elts;
    int offset;
    int depth;
*************** struct initializer_stack
*** 4636,4642 ****
    tree decl;
    struct constructor_stack *constructor_stack;
    struct constructor_range_stack *constructor_range_stack;
!   tree elements;
    struct spelling *spelling;
    struct spelling *spelling_base;
    int spelling_size;
--- 4638,4644 ----
    tree decl;
    struct constructor_stack *constructor_stack;
    struct constructor_range_stack *constructor_range_stack;
!   VEC(constructor_elt,gc) *elements;
    struct spelling *spelling;
    struct spelling *spelling_base;
    int spelling_size;
*************** push_init_level (int implicit)
*** 4971,4977 ****
        constructor_constant = TREE_CONSTANT (value);
        constructor_simple = TREE_STATIC (value);
        constructor_elements = CONSTRUCTOR_ELTS (value);
!       if (constructor_elements
  	  && (TREE_CODE (constructor_type) == RECORD_TYPE
  	      || TREE_CODE (constructor_type) == ARRAY_TYPE))
  	set_nonincremental_init ();
--- 4973,4979 ----
        constructor_constant = TREE_CONSTANT (value);
        constructor_simple = TREE_STATIC (value);
        constructor_elements = CONSTRUCTOR_ELTS (value);
!       if (!VEC_empty (constructor_elt, constructor_elements)
  	  && (TREE_CODE (constructor_type) == RECORD_TYPE
  	      || TREE_CODE (constructor_type) == ARRAY_TYPE))
  	set_nonincremental_init ();
*************** pop_init_level (int implicit)
*** 5146,5164 ****
      {
        /* A nonincremental scalar initializer--just return
  	 the element, after verifying there is just one.  */
!       if (constructor_elements == 0)
  	{
  	  if (!constructor_erroneous)
  	    error_init ("empty scalar initializer");
  	  ret.value = error_mark_node;
  	}
!       else if (TREE_CHAIN (constructor_elements) != 0)
  	{
  	  error_init ("extra elements in scalar initializer");
! 	  ret.value = TREE_VALUE (constructor_elements);
  	}
        else
! 	ret.value = TREE_VALUE (constructor_elements);
      }
    else
      {
--- 5148,5166 ----
      {
        /* A nonincremental scalar initializer--just return
  	 the element, after verifying there is just one.  */
!       if (VEC_empty (constructor_elt,constructor_elements))
  	{
  	  if (!constructor_erroneous)
  	    error_init ("empty scalar initializer");
  	  ret.value = error_mark_node;
  	}
!       else if (VEC_length (constructor_elt,constructor_elements) != 1)
  	{
  	  error_init ("extra elements in scalar initializer");
! 	  ret.value = VEC_index (constructor_elt,constructor_elements,0)->value;
  	}
        else
! 	ret.value = VEC_index (constructor_elt,constructor_elements,0)->value;
      }
    else
      {
*************** pop_init_level (int implicit)
*** 5167,5173 ****
        else
  	{
  	  ret.value = build_constructor (constructor_type,
! 					 nreverse (constructor_elements));
  	  if (constructor_constant)
  	    TREE_CONSTANT (ret.value) = TREE_INVARIANT (ret.value) = 1;
  	  if (constructor_constant && constructor_simple)
--- 5169,5175 ----
        else
  	{
  	  ret.value = build_constructor (constructor_type,
! 					 constructor_elements);
  	  if (constructor_constant)
  	    TREE_CONSTANT (ret.value) = TREE_INVARIANT (ret.value) = 1;
  	  if (constructor_constant && constructor_simple)
*************** add_pending_init (tree purpose, tree val
*** 5616,5629 ****
  static void
  set_nonincremental_init (void)
  {
!   tree chain;
  
    if (TREE_CODE (constructor_type) != RECORD_TYPE
        && TREE_CODE (constructor_type) != ARRAY_TYPE)
      return;
  
!   for (chain = constructor_elements; chain; chain = TREE_CHAIN (chain))
!     add_pending_init (TREE_PURPOSE (chain), TREE_VALUE (chain));
    constructor_elements = 0;
    if (TREE_CODE (constructor_type) == RECORD_TYPE)
      {
--- 5618,5632 ----
  static void
  set_nonincremental_init (void)
  {
!   unsigned HOST_WIDE_INT ix;
!   tree index, value;
  
    if (TREE_CODE (constructor_type) != RECORD_TYPE
        && TREE_CODE (constructor_type) != ARRAY_TYPE)
      return;
  
!   FOR_EACH_CONSTRUCTOR_ELT (constructor_elements, ix, index, value)
!     add_pending_init (index, value);
    constructor_elements = 0;
    if (TREE_CODE (constructor_type) == RECORD_TYPE)
      {
*************** find_init_member (tree field)
*** 5775,5783 ****
      }
    else if (TREE_CODE (constructor_type) == UNION_TYPE)
      {
!       if (constructor_elements
! 	  && TREE_PURPOSE (constructor_elements) == field)
! 	return TREE_VALUE (constructor_elements);
      }
    return 0;
  }
--- 5778,5787 ----
      }
    else if (TREE_CODE (constructor_type) == UNION_TYPE)
      {
!       if (!VEC_empty (constructor_elt, constructor_elements)
! 	  && (VEC_last (constructor_elt, constructor_elements)->index
! 	      == field))
! 	return VEC_last (constructor_elt, constructor_elements)->value;
      }
    return 0;
  }
*************** static void
*** 5799,5804 ****
--- 5803,5810 ----
  output_init_element (tree value, bool strict_string, tree type, tree field,
  		     int pending)
  {
+   constructor_elt *celt;
+ 
    if (type == error_mark_node || value == error_mark_node)
      {
        constructor_erroneous = 1;
*************** output_init_element (tree value, bool st
*** 5903,5911 ****
        return;
      }
    else if (TREE_CODE (constructor_type) == UNION_TYPE
! 	   && constructor_elements)
      {
!       if (TREE_SIDE_EFFECTS (TREE_VALUE (constructor_elements)))
  	warning_init ("initialized field with side-effects overwritten");
  
        /* We can have just one union field set.  */
--- 5909,5918 ----
        return;
      }
    else if (TREE_CODE (constructor_type) == UNION_TYPE
! 	   && !VEC_empty (constructor_elt, constructor_elements))
      {
!       if (TREE_SIDE_EFFECTS (VEC_last (constructor_elt,
! 				       constructor_elements)->value))
  	warning_init ("initialized field with side-effects overwritten");
  
        /* We can have just one union field set.  */
*************** output_init_element (tree value, bool st
*** 5917,5924 ****
  
    if (field && TREE_CODE (field) == INTEGER_CST)
      field = copy_node (field);
!   constructor_elements
!     = tree_cons (field, value, constructor_elements);
  
    /* Advance the variable that indicates sequential elements output.  */
    if (TREE_CODE (constructor_type) == ARRAY_TYPE)
--- 5924,5932 ----
  
    if (field && TREE_CODE (field) == INTEGER_CST)
      field = copy_node (field);
!   celt = VEC_safe_push (constructor_elt, gc, constructor_elements, NULL);
!   celt->index = field;
!   celt->value = value;
  
    /* Advance the variable that indicates sequential elements output.  */
    if (TREE_CODE (constructor_type) == ARRAY_TYPE)
Index: coverage.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/coverage.c,v
retrieving revision 1.53
diff -c -p -r1.53 coverage.c
*** coverage.c	3 Jul 2005 21:07:51 -0000	1.53
--- coverage.c	9 Jul 2005 15:24:18 -0000
*************** build_fn_info_value (const struct functi
*** 672,681 ****
  	array_value = tree_cons (NULL_TREE, counters, array_value);
        }
  
!   array_value = build_constructor (TREE_TYPE (fields), nreverse (array_value));
    value = tree_cons (fields, array_value, value);
  
!   value = build_constructor (type, nreverse (value));
  
    return value;
  }
--- 672,684 ----
  	array_value = tree_cons (NULL_TREE, counters, array_value);
        }
  
!   /* FIXME: use build_constructor directly.  */
!   array_value = build_constructor_from_list (TREE_TYPE (fields),
! 					     nreverse (array_value));
    value = tree_cons (fields, array_value, value);
  
!   /* FIXME: use build_constructor directly.  */
!   value = build_constructor_from_list (type, nreverse (value));
  
    return value;
  }
*************** build_ctr_info_value (unsigned int count
*** 768,774 ****
  		     build1 (ADDR_EXPR, TREE_TYPE (fields), fn),
  		     value);
  
!   value = build_constructor (type, nreverse (value));
  
    return value;
  }
--- 771,778 ----
  		     build1 (ADDR_EXPR, TREE_TYPE (fields), fn),
  		     value);
  
!   /* FIXME: use build_constructor directly.  */
!   value = build_constructor_from_list (type, nreverse (value));
  
    return value;
  }
*************** build_gcov_info (void)
*** 856,862 ****
        array_type = build_index_type (build_int_cst (NULL_TREE, n_fns - 1));
        array_type = build_array_type (fn_info_type, array_type);
  
!       fn_info_value = build_constructor (array_type, nreverse (fn_info_value));
        fn_info_value = build1 (ADDR_EXPR, fn_info_ptr_type, fn_info_value);
      }
    else
--- 860,868 ----
        array_type = build_index_type (build_int_cst (NULL_TREE, n_fns - 1));
        array_type = build_array_type (fn_info_type, array_type);
  
!       /* FIXME: use build_constructor directly.  */
!       fn_info_value = build_constructor_from_list (array_type,
! 						   nreverse (fn_info_value));
        fn_info_value = build1 (ADDR_EXPR, fn_info_ptr_type, fn_info_value);
      }
    else
*************** build_gcov_info (void)
*** 894,901 ****
        ctr_info_value = tree_cons (NULL_TREE,
  				  build_ctr_info_value (ix, ctr_info_type),
  				  ctr_info_value);
!   ctr_info_value = build_constructor (ctr_info_ary_type,
! 				      nreverse (ctr_info_value));
  
    field = build_decl (FIELD_DECL, NULL_TREE, ctr_info_ary_type);
    TREE_CHAIN (field) = fields;
--- 900,908 ----
        ctr_info_value = tree_cons (NULL_TREE,
  				  build_ctr_info_value (ix, ctr_info_type),
  				  ctr_info_value);
!   /* FIXME: use build_constructor directly.  */
!   ctr_info_value = build_constructor_from_list (ctr_info_ary_type,
! 				                nreverse (ctr_info_value));
  
    field = build_decl (FIELD_DECL, NULL_TREE, ctr_info_ary_type);
    TREE_CHAIN (field) = fields;
*************** build_gcov_info (void)
*** 904,910 ****
  
    finish_builtin_struct (type, "__gcov_info", fields, NULL_TREE);
  
!   value = build_constructor (type, nreverse (value));
  
    return value;
  }
--- 911,918 ----
  
    finish_builtin_struct (type, "__gcov_info", fields, NULL_TREE);
  
!   /* FIXME: use build_constructor directly.  */
!   value = build_constructor_from_list (type, nreverse (value));
  
    return value;
  }
Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.802
diff -c -p -r1.802 expr.c
*** expr.c	7 Jul 2005 10:21:05 -0000	1.802
--- expr.c	9 Jul 2005 15:24:21 -0000
*************** categorize_ctor_elements_1 (tree ctor, H
*** 4380,4396 ****
  			    HOST_WIDE_INT *p_elt_count,
  			    bool *p_must_clear)
  {
    HOST_WIDE_INT nz_elts, nc_elts, elt_count;
!   tree list;
  
    nz_elts = 0;
    nc_elts = 0;
    elt_count = 0;
  
!   for (list = CONSTRUCTOR_ELTS (ctor); list; list = TREE_CHAIN (list))
      {
-       tree value = TREE_VALUE (list);
-       tree purpose = TREE_PURPOSE (list);
        HOST_WIDE_INT mult;
  
        mult = 1;
--- 4380,4395 ----
  			    HOST_WIDE_INT *p_elt_count,
  			    bool *p_must_clear)
  {
+   unsigned HOST_WIDE_INT idx;
    HOST_WIDE_INT nz_elts, nc_elts, elt_count;
!   tree value, purpose;
  
    nz_elts = 0;
    nc_elts = 0;
    elt_count = 0;
  
!   FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), idx, purpose, value)
      {
        HOST_WIDE_INT mult;
  
        mult = 1;
*************** categorize_ctor_elements_1 (tree ctor, H
*** 4464,4477 ****
        tree init_sub_type;
        bool clear_this = true;
  
!       list = CONSTRUCTOR_ELTS (ctor);
!       if (list)
  	{
  	  /* We don't expect more than one element of the union to be
  	     initialized.  Not sure what we should do otherwise... */
!           gcc_assert (TREE_CHAIN (list) == NULL);
  
!           init_sub_type = TREE_TYPE (TREE_VALUE (list));
  
  	  /* ??? We could look at each element of the union, and find the
  	     largest element.  Which would avoid comparing the size of the
--- 4463,4478 ----
        tree init_sub_type;
        bool clear_this = true;
  
!       if (!VEC_empty (constructor_elt, CONSTRUCTOR_ELTS (ctor)))
  	{
  	  /* We don't expect more than one element of the union to be
  	     initialized.  Not sure what we should do otherwise... */
!           gcc_assert (VEC_length (constructor_elt, CONSTRUCTOR_ELTS (ctor))
! 		      == 1);
  
!           init_sub_type = TREE_TYPE (VEC_index (constructor_elt,
! 						CONSTRUCTOR_ELTS (ctor),
! 						0)->value);
  
  	  /* ??? We could look at each element of the union, and find the
  	     largest element.  Which would avoid comparing the size of the
*************** store_constructor (tree exp, rtx target,
*** 4681,4687 ****
      case UNION_TYPE:
      case QUAL_UNION_TYPE:
        {
! 	tree elt;
  
  	/* If size is zero or the target is already cleared, do nothing.  */
  	if (size == 0 || cleared)
--- 4682,4689 ----
      case UNION_TYPE:
      case QUAL_UNION_TYPE:
        {
! 	unsigned HOST_WIDE_INT idx;
! 	tree field, value;
  
  	/* If size is zero or the target is already cleared, do nothing.  */
  	if (size == 0 || cleared)
*************** store_constructor (tree exp, rtx target,
*** 4713,4719 ****
  	   register whose mode size isn't equal to SIZE since
  	   clear_storage can't handle this case.  */
  	else if (size > 0
! 		 && ((list_length (CONSTRUCTOR_ELTS (exp))
  		      != fields_length (type))
  		     || mostly_zeros_p (exp))
  		 && (!REG_P (target)
--- 4715,4721 ----
  	   register whose mode size isn't equal to SIZE since
  	   clear_storage can't handle this case.  */
  	else if (size > 0
! 		 && (((int)VEC_length (constructor_elt, CONSTRUCTOR_ELTS (exp))
  		      != fields_length (type))
  		     || mostly_zeros_p (exp))
  		 && (!REG_P (target)
*************** store_constructor (tree exp, rtx target,
*** 4729,4739 ****
  
  	/* Store each element of the constructor into the
  	   corresponding field of TARGET.  */
! 
! 	for (elt = CONSTRUCTOR_ELTS (exp); elt; elt = TREE_CHAIN (elt))
  	  {
- 	    tree field = TREE_PURPOSE (elt);
- 	    tree value = TREE_VALUE (elt);
  	    enum machine_mode mode;
  	    HOST_WIDE_INT bitsize;
  	    HOST_WIDE_INT bitpos = 0;
--- 4731,4738 ----
  
  	/* Store each element of the constructor into the
  	   corresponding field of TARGET.  */
! 	FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (exp), idx, field, value)
  	  {
  	    enum machine_mode mode;
  	    HOST_WIDE_INT bitsize;
  	    HOST_WIDE_INT bitpos = 0;
*************** store_constructor (tree exp, rtx target,
*** 4839,4846 ****
        }
      case ARRAY_TYPE:
        {
! 	tree elt;
! 	int i;
  	int need_to_clear;
  	tree domain;
  	tree elttype = TREE_TYPE (type);
--- 4838,4845 ----
        }
      case ARRAY_TYPE:
        {
! 	tree value, index;
! 	unsigned HOST_WIDE_INT i;
  	int need_to_clear;
  	tree domain;
  	tree elttype = TREE_TYPE (type);
*************** store_constructor (tree exp, rtx target,
*** 4870,4887 ****
  	  need_to_clear = 1;
  	else
  	  {
  	    HOST_WIDE_INT count = 0, zero_count = 0;
  	    need_to_clear = ! const_bounds_p;
  	    
  	    /* This loop is a more accurate version of the loop in
  	       mostly_zeros_p (it handles RANGE_EXPR in an index).  It
  	       is also needed to check for missing elements.  */
! 	    for (elt = CONSTRUCTOR_ELTS (exp);
! 		 elt != NULL_TREE && ! need_to_clear;
! 		 elt = TREE_CHAIN (elt))
  	      {
- 		tree index = TREE_PURPOSE (elt);
  		HOST_WIDE_INT this_node_count;
  		
  		if (index != NULL_TREE && TREE_CODE (index) == RANGE_EXPR)
  		  {
--- 4869,4888 ----
  	  need_to_clear = 1;
  	else
  	  {
+ 	    unsigned HOST_WIDE_INT idx;
+ 	    tree index, value;
  	    HOST_WIDE_INT count = 0, zero_count = 0;
  	    need_to_clear = ! const_bounds_p;
  	    
  	    /* This loop is a more accurate version of the loop in
  	       mostly_zeros_p (it handles RANGE_EXPR in an index).  It
  	       is also needed to check for missing elements.  */
! 	    FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (exp), idx, index, value)
  	      {
  		HOST_WIDE_INT this_node_count;
+ 
+ 		if (need_to_clear)
+ 		  break;
  		
  		if (index != NULL_TREE && TREE_CODE (index) == RANGE_EXPR)
  		  {
*************** store_constructor (tree exp, rtx target,
*** 4902,4908 ****
  		  this_node_count = 1;
  		
  		count += this_node_count;
! 		if (mostly_zeros_p (TREE_VALUE (elt)))
  		  zero_count += this_node_count;
  	      }
  	    
--- 4903,4909 ----
  		  this_node_count = 1;
  		
  		count += this_node_count;
! 		if (mostly_zeros_p (value))
  		  zero_count += this_node_count;
  	      }
  	    
*************** store_constructor (tree exp, rtx target,
*** 4931,4946 ****
  	/* Store each element of the constructor into the
  	   corresponding element of TARGET, determined by counting the
  	   elements.  */
! 	for (elt = CONSTRUCTOR_ELTS (exp), i = 0;
! 	     elt;
! 	     elt = TREE_CHAIN (elt), i++)
  	  {
  	    enum machine_mode mode;
  	    HOST_WIDE_INT bitsize;
  	    HOST_WIDE_INT bitpos;
  	    int unsignedp;
- 	    tree value = TREE_VALUE (elt);
- 	    tree index = TREE_PURPOSE (elt);
  	    rtx xtarget = target;
  	    
  	    if (cleared && initializer_zerop (value))
--- 4932,4943 ----
  	/* Store each element of the constructor into the
  	   corresponding element of TARGET, determined by counting the
  	   elements.  */
! 	FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (exp), i, index, value)
  	  {
  	    enum machine_mode mode;
  	    HOST_WIDE_INT bitsize;
  	    HOST_WIDE_INT bitpos;
  	    int unsignedp;
  	    rtx xtarget = target;
  	    
  	    if (cleared && initializer_zerop (value))
*************** store_constructor (tree exp, rtx target,
*** 5100,5106 ****
  
      case VECTOR_TYPE:
        {
! 	tree elt;
  	int i;
  	int need_to_clear;
  	int icode = 0;
--- 5097,5104 ----
  
      case VECTOR_TYPE:
        {
! 	unsigned HOST_WIDE_INT idx;
! 	constructor_elt *ce;
  	int i;
  	int need_to_clear;
  	int icode = 0;
*************** store_constructor (tree exp, rtx target,
*** 5140,5157 ****
  	else
  	  {
  	    unsigned HOST_WIDE_INT count = 0, zero_count = 0;
  	    
! 	    for (elt = CONSTRUCTOR_ELTS (exp);
! 		 elt != NULL_TREE;
! 		 elt = TREE_CHAIN (elt))
  	      {
  		int n_elts_here = tree_low_cst
  		  (int_const_binop (TRUNC_DIV_EXPR,
! 				    TYPE_SIZE (TREE_TYPE (TREE_VALUE (elt))),
  				    TYPE_SIZE (elttype), 0), 1);
  		
  		count += n_elts_here;
! 		if (mostly_zeros_p (TREE_VALUE (elt)))
  		  zero_count += n_elts_here;
  	      }
  
--- 5138,5154 ----
  	else
  	  {
  	    unsigned HOST_WIDE_INT count = 0, zero_count = 0;
+ 	    tree value;
  	    
! 	    FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (exp), idx, value)
  	      {
  		int n_elts_here = tree_low_cst
  		  (int_const_binop (TRUNC_DIV_EXPR,
! 				    TYPE_SIZE (TREE_TYPE (value)),
  				    TYPE_SIZE (elttype), 0), 1);
  		
  		count += n_elts_here;
! 		if (mostly_zeros_p (value))
  		  zero_count += n_elts_here;
  	      }
  
*************** store_constructor (tree exp, rtx target,
*** 5175,5194 ****
  
          /* Store each element of the constructor into the corresponding
  	   element of TARGET, determined by counting the elements.  */
! 	for (elt = CONSTRUCTOR_ELTS (exp), i = 0;
! 	     elt;
! 	     elt = TREE_CHAIN (elt), i += bitsize / elt_size)
  	  {
- 	    tree value = TREE_VALUE (elt);
- 	    tree index = TREE_PURPOSE (elt);
  	    HOST_WIDE_INT eltpos;
  	    
  	    bitsize = tree_low_cst (TYPE_SIZE (TREE_TYPE (value)), 1);
  	    if (cleared && initializer_zerop (value))
  	      continue;
  	    
! 	    if (index != 0)
! 	      eltpos = tree_low_cst (index, 1);
  	    else
  	      eltpos = i;
  	    
--- 5172,5190 ----
  
          /* Store each element of the constructor into the corresponding
  	   element of TARGET, determined by counting the elements.  */
! 	for (idx = 0, i = 0;
! 	     VEC_iterate (constructor_elt, CONSTRUCTOR_ELTS (exp), idx, ce);
! 	     idx++, i += bitsize / elt_size)
  	  {
  	    HOST_WIDE_INT eltpos;
+ 	    tree value = ce->value;
  	    
  	    bitsize = tree_low_cst (TYPE_SIZE (TREE_TYPE (value)), 1);
  	    if (cleared && initializer_zerop (value))
  	      continue;
  	    
! 	    if (ce->index)
! 	      eltpos = tree_low_cst (ce->index, 1);
  	    else
  	      eltpos = i;
  	    
*************** expand_expr_real_1 (tree exp, rtx target
*** 6715,6722 ****
  	  || GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (exp))) == MODE_VECTOR_FLOAT)
  	return const_vector_from_tree (exp);
        else
! 	return expand_expr (build1 (CONSTRUCTOR, TREE_TYPE (exp),
! 				    TREE_VECTOR_CST_ELTS (exp)),
  			    ignore ? const0_rtx : target, tmode, modifier);
  
      case CONST_DECL:
--- 6711,6719 ----
  	  || GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (exp))) == MODE_VECTOR_FLOAT)
  	return const_vector_from_tree (exp);
        else
! 	return expand_expr (build_constructor_from_list
! 			    (TREE_TYPE (exp),
! 			     TREE_VECTOR_CST_ELTS (exp)),
  			    ignore ? const0_rtx : target, tmode, modifier);
  
      case CONST_DECL:
*************** expand_expr_real_1 (tree exp, rtx target
*** 6814,6823 ****
  	 subexpressions.  */
        if (ignore)
  	{
! 	  tree elt;
  
! 	  for (elt = CONSTRUCTOR_ELTS (exp); elt; elt = TREE_CHAIN (elt))
! 	    expand_expr (TREE_VALUE (elt), const0_rtx, VOIDmode, 0);
  
  	  return const0_rtx;
  	}
--- 6811,6821 ----
  	 subexpressions.  */
        if (ignore)
  	{
! 	  unsigned HOST_WIDE_INT idx;
! 	  tree value;
  
! 	  FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (exp), idx, value)
! 	    expand_expr (value, const0_rtx, VOIDmode, 0);
  
  	  return const0_rtx;
  	}
*************** expand_expr_real_1 (tree exp, rtx target
*** 6979,6994 ****
  	    && ! TREE_SIDE_EFFECTS (array)
  	    && TREE_CODE (index) == INTEGER_CST)
  	  {
! 	    tree elem;
  
! 	    for (elem = CONSTRUCTOR_ELTS (array);
! 		 (elem && !tree_int_cst_equal (TREE_PURPOSE (elem), index));
! 		 elem = TREE_CHAIN (elem))
! 	      ;
! 
! 	    if (elem && !TREE_SIDE_EFFECTS (TREE_VALUE (elem)))
! 	      return expand_expr (fold (TREE_VALUE (elem)), target, tmode,
! 				  modifier);
  	  }
  
  	else if (optimize >= 1
--- 6977,6993 ----
  	    && ! TREE_SIDE_EFFECTS (array)
  	    && TREE_CODE (index) == INTEGER_CST)
  	  {
! 	    unsigned HOST_WIDE_INT ix;
! 	    tree field, value;
  
! 	    FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (array), ix,
! 				      field, value)
! 	      if (tree_int_cst_equal (field, index))
! 		{
! 		  if (!TREE_SIDE_EFFECTS (value))
! 		    return expand_expr (fold (value), target, tmode, modifier);
! 		  break;
! 		}
  	  }
  
  	else if (optimize >= 1
*************** expand_expr_real_1 (tree exp, rtx target
*** 7006,7022 ****
  
  		if (TREE_CODE (init) == CONSTRUCTOR)
  		  {
! 		    tree elem;
  
! 		    for (elem = CONSTRUCTOR_ELTS (init);
! 			 (elem
! 			  && !tree_int_cst_equal (TREE_PURPOSE (elem), index));
! 			 elem = TREE_CHAIN (elem))
! 		      ;
! 
! 		    if (elem && !TREE_SIDE_EFFECTS (TREE_VALUE (elem)))
! 		      return expand_expr (fold (TREE_VALUE (elem)), target,
! 					  tmode, modifier);
  		  }
  		else if (TREE_CODE (init) == STRING_CST
  			 && 0 > compare_tree_int (index,
--- 7005,7022 ----
  
  		if (TREE_CODE (init) == CONSTRUCTOR)
  		  {
! 		    unsigned HOST_WIDE_INT ix;
! 		    tree field, value;
  
! 		    FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (init), ix,
! 					      field, value)
! 		      if (tree_int_cst_equal (field, index))
! 			{
! 			  if (!TREE_SIDE_EFFECTS (value))
! 			    return expand_expr (fold (value), target, tmode,
! 						modifier);
! 			  break;
! 			}
  		  }
  		else if (TREE_CODE (init) == STRING_CST
  			 && 0 > compare_tree_int (index,
*************** expand_expr_real_1 (tree exp, rtx target
*** 7040,7050 ****
  	 appropriate field if it is present.  */
        if (TREE_CODE (TREE_OPERAND (exp, 0)) == CONSTRUCTOR)
  	{
! 	  tree elt;
  
! 	  for (elt = CONSTRUCTOR_ELTS (TREE_OPERAND (exp, 0)); elt;
! 	       elt = TREE_CHAIN (elt))
! 	    if (TREE_PURPOSE (elt) == TREE_OPERAND (exp, 1)
  		/* We can normally use the value of the field in the
  		   CONSTRUCTOR.  However, if this is a bitfield in
  		   an integral mode that we can fit in a HOST_WIDE_INT,
--- 7040,7051 ----
  	 appropriate field if it is present.  */
        if (TREE_CODE (TREE_OPERAND (exp, 0)) == CONSTRUCTOR)
  	{
! 	  unsigned HOST_WIDE_INT idx;
! 	  tree field, value;
  
! 	  FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (TREE_OPERAND (exp, 0)),
! 				    idx, field, value)
! 	    if (field == TREE_OPERAND (exp, 1)
  		/* We can normally use the value of the field in the
  		   CONSTRUCTOR.  However, if this is a bitfield in
  		   an integral mode that we can fit in a HOST_WIDE_INT,
*************** expand_expr_real_1 (tree exp, rtx target
*** 7052,7075 ****
  		   since this is done implicitly by the constructor.  If
  		   the bitfield does not meet either of those conditions,
  		   we can't do this optimization.  */
! 		&& (! DECL_BIT_FIELD (TREE_PURPOSE (elt))
! 		    || ((GET_MODE_CLASS (DECL_MODE (TREE_PURPOSE (elt)))
! 			 == MODE_INT)
! 			&& (GET_MODE_BITSIZE (DECL_MODE (TREE_PURPOSE (elt)))
  			    <= HOST_BITS_PER_WIDE_INT))))
  	      {
! 		if (DECL_BIT_FIELD (TREE_PURPOSE (elt))
  		    && modifier == EXPAND_STACK_PARM)
  		  target = 0;
! 		op0 = expand_expr (TREE_VALUE (elt), target, tmode, modifier);
! 		if (DECL_BIT_FIELD (TREE_PURPOSE (elt)))
  		  {
! 		    HOST_WIDE_INT bitsize
! 		      = TREE_INT_CST_LOW (DECL_SIZE (TREE_PURPOSE (elt)));
! 		    enum machine_mode imode
! 		      = TYPE_MODE (TREE_TYPE (TREE_PURPOSE (elt)));
  
! 		    if (TYPE_UNSIGNED (TREE_TYPE (TREE_PURPOSE (elt))))
  		      {
  			op1 = GEN_INT (((HOST_WIDE_INT) 1 << bitsize) - 1);
  			op0 = expand_and (imode, op0, op1, target);
--- 7053,7073 ----
  		   since this is done implicitly by the constructor.  If
  		   the bitfield does not meet either of those conditions,
  		   we can't do this optimization.  */
! 		&& (! DECL_BIT_FIELD (field)
! 		    || ((GET_MODE_CLASS (DECL_MODE (field)) == MODE_INT)
! 			&& (GET_MODE_BITSIZE (DECL_MODE (field))
  			    <= HOST_BITS_PER_WIDE_INT))))
  	      {
! 		if (DECL_BIT_FIELD (field)
  		    && modifier == EXPAND_STACK_PARM)
  		  target = 0;
! 		op0 = expand_expr (value, target, tmode, modifier);
! 		if (DECL_BIT_FIELD (field))
  		  {
! 		    HOST_WIDE_INT bitsize = TREE_INT_CST_LOW (DECL_SIZE (field));
! 		    enum machine_mode imode = TYPE_MODE (TREE_TYPE (field));
  
! 		    if (TYPE_UNSIGNED (TREE_TYPE (field)))
  		      {
  			op1 = GEN_INT (((HOST_WIDE_INT) 1 << bitsize) - 1);
  			op0 = expand_and (imode, op0, op1, target);
Index: fold-const.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v
retrieving revision 1.601
diff -c -p -r1.601 fold-const.c
*** fold-const.c	8 Jul 2005 23:36:39 -0000	1.601
--- fold-const.c	9 Jul 2005 15:24:24 -0000
*************** fold_ternary (enum tree_code code, tree 
*** 9844,9852 ****
        if (TREE_CODE (arg0) == CONSTRUCTOR
  	  && ! type_contains_placeholder_p (TREE_TYPE (arg0)))
  	{
! 	  tree m = purpose_member (arg1, CONSTRUCTOR_ELTS (arg0));
! 	  if (m)
! 	    return TREE_VALUE (m);
  	}
        return NULL_TREE;
  
--- 9844,9854 ----
        if (TREE_CODE (arg0) == CONSTRUCTOR
  	  && ! type_contains_placeholder_p (TREE_TYPE (arg0)))
  	{
! 	  unsigned HOST_WIDE_INT idx;
! 	  tree field, value;
! 	  FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (arg0), idx, field, value)
! 	    if (field == arg1)
! 	      return value;
  	}
        return NULL_TREE;
  
Index: gimplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gimplify.c,v
retrieving revision 2.140
diff -c -p -r2.140 gimplify.c
*** gimplify.c	8 Jul 2005 23:36:40 -0000	2.140
--- gimplify.c	9 Jul 2005 15:24:25 -0000
*************** gimplify_init_ctor_preeval (tree *expr_p
*** 2385,2393 ****
    /* Recurse for nested constructors.  */
    if (TREE_CODE (*expr_p) == CONSTRUCTOR)
      {
!       tree list;
!       for (list = CONSTRUCTOR_ELTS (*expr_p); list ; list = TREE_CHAIN (list))
! 	gimplify_init_ctor_preeval (&TREE_VALUE (list), pre_p, post_p, data);
        return;
      }
  
--- 2385,2396 ----
    /* Recurse for nested constructors.  */
    if (TREE_CODE (*expr_p) == CONSTRUCTOR)
      {
!       unsigned HOST_WIDE_INT ix;
!       constructor_elt *ce;
!       VEC(constructor_elt,gc) *v = CONSTRUCTOR_ELTS (*expr_p);
! 
!       for (ix = 0; VEC_iterate (constructor_elt, v, ix, ce); ix++)
! 	gimplify_init_ctor_preeval (&ce->value, pre_p, post_p, data);
        return;
      }
  
*************** gimplify_init_ctor_preeval (tree *expr_p
*** 2446,2452 ****
     Note that we never have to deal with SAVE_EXPRs here, because this has
     already been taken care of for us, in gimplify_init_ctor_preeval().  */
  
! static void gimplify_init_ctor_eval (tree, tree, tree *, bool);
  
  static void
  gimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
--- 2449,2456 ----
     Note that we never have to deal with SAVE_EXPRs here, because this has
     already been taken care of for us, in gimplify_init_ctor_preeval().  */
  
! static void gimplify_init_ctor_eval (tree, VEC(constructor_elt,gc) *,
! 				     tree *, bool);
  
  static void
  gimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
*************** zero_sized_field_decl (tree fdecl)
*** 2530,2553 ****
  
  /* A subroutine of gimplify_init_constructor.  Generate individual
     MODIFY_EXPRs for a CONSTRUCTOR.  OBJECT is the LHS against which the
!    assignments should happen.  LIST is the CONSTRUCTOR_ELTS of the
     CONSTRUCTOR.  CLEARED is true if the entire LHS object has been
     zeroed first.  */
  
  static void
! gimplify_init_ctor_eval (tree object, tree list, tree *pre_p, bool cleared)
  {
    tree array_elt_type = NULL;
  
    if (TREE_CODE (TREE_TYPE (object)) == ARRAY_TYPE)
      array_elt_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object)));
  
!   for (; list; list = TREE_CHAIN (list))
      {
!       tree purpose, value, cref, init;
! 
!       purpose = TREE_PURPOSE (list);
!       value = TREE_VALUE (list);
  
        /* NULL values are created above for gimplification errors.  */
        if (value == NULL)
--- 2534,2557 ----
  
  /* A subroutine of gimplify_init_constructor.  Generate individual
     MODIFY_EXPRs for a CONSTRUCTOR.  OBJECT is the LHS against which the
!    assignments should happen.  ELTS is the CONSTRUCTOR_ELTS of the
     CONSTRUCTOR.  CLEARED is true if the entire LHS object has been
     zeroed first.  */
  
  static void
! gimplify_init_ctor_eval (tree object, VEC(constructor_elt,gc) *elts,
! 			 tree *pre_p, bool cleared)
  {
    tree array_elt_type = NULL;
+   unsigned HOST_WIDE_INT ix;
+   tree purpose, value;
  
    if (TREE_CODE (TREE_TYPE (object)) == ARRAY_TYPE)
      array_elt_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object)));
  
!   FOR_EACH_CONSTRUCTOR_ELT (elts, ix, purpose, value)
      {
!       tree cref, init;
  
        /* NULL values are created above for gimplification errors.  */
        if (value == NULL)
*************** gimplify_init_constructor (tree *expr_p,
*** 2617,2623 ****
    tree ctor = TREE_OPERAND (*expr_p, 1);
    tree type = TREE_TYPE (ctor);
    enum gimplify_status ret;
!   tree elt_list;
  
    if (TREE_CODE (ctor) != CONSTRUCTOR)
      return GS_UNHANDLED;
--- 2621,2627 ----
    tree ctor = TREE_OPERAND (*expr_p, 1);
    tree type = TREE_TYPE (ctor);
    enum gimplify_status ret;
!   VEC(constructor_elt,gc) *elts;
  
    if (TREE_CODE (ctor) != CONSTRUCTOR)
      return GS_UNHANDLED;
*************** gimplify_init_constructor (tree *expr_p,
*** 2628,2634 ****
      return ret;
    object = TREE_OPERAND (*expr_p, 0);
  
!   elt_list = CONSTRUCTOR_ELTS (ctor);
  
    ret = GS_ALL_DONE;
    switch (TREE_CODE (type))
--- 2632,2638 ----
      return ret;
    object = TREE_OPERAND (*expr_p, 0);
  
!   elts = CONSTRUCTOR_ELTS (ctor);
  
    ret = GS_ALL_DONE;
    switch (TREE_CODE (type))
*************** gimplify_init_constructor (tree *expr_p,
*** 2646,2652 ****
  	/* Aggregate types must lower constructors to initialization of
  	   individual elements.  The exception is that a CONSTRUCTOR node
  	   with no elements indicates zero-initialization of the whole.  */
! 	if (elt_list == NULL)
  	  break;
  
  	categorize_ctor_elements (ctor, &num_nonzero_elements,
--- 2650,2656 ----
  	/* Aggregate types must lower constructors to initialization of
  	   individual elements.  The exception is that a CONSTRUCTOR node
  	   with no elements indicates zero-initialization of the whole.  */
! 	if (VEC_empty (constructor_elt, elts))
  	  break;
  
  	categorize_ctor_elements (ctor, &num_nonzero_elements,
*************** gimplify_init_constructor (tree *expr_p,
*** 2758,2764 ****
  	    /* Zap the CONSTRUCTOR element list, which simplifies this case.
  	       Note that we still have to gimplify, in order to handle the
  	       case of variable sized types.  Avoid shared tree structures.  */
! 	    CONSTRUCTOR_ELTS (ctor) = NULL_TREE;
  	    object = unshare_expr (object);
  	    gimplify_stmt (expr_p);
  	    append_to_statement_list (*expr_p, pre_p);
--- 2762,2768 ----
  	    /* Zap the CONSTRUCTOR element list, which simplifies this case.
  	       Note that we still have to gimplify, in order to handle the
  	       case of variable sized types.  Avoid shared tree structures.  */
! 	    CONSTRUCTOR_ELTS (ctor) = NULL;
  	    object = unshare_expr (object);
  	    gimplify_stmt (expr_p);
  	    append_to_statement_list (*expr_p, pre_p);
*************** gimplify_init_constructor (tree *expr_p,
*** 2776,2782 ****
  
  	    gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p, 1),
  					pre_p, post_p, &preeval_data);
! 	    gimplify_init_ctor_eval (object, elt_list, pre_p, cleared);
  	  }
  
  	*expr_p = NULL_TREE;
--- 2780,2786 ----
  
  	    gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p, 1),
  					pre_p, post_p, &preeval_data);
! 	    gimplify_init_ctor_eval (object, elts, pre_p, cleared);
  	  }
  
  	*expr_p = NULL_TREE;
*************** gimplify_init_constructor (tree *expr_p,
*** 2788,2804 ****
  	tree r, i;
  
  	/* Extract the real and imaginary parts out of the ctor.  */
! 	r = i = NULL_TREE;
! 	if (elt_list)
! 	  {
! 	    r = TREE_VALUE (elt_list);
! 	    elt_list = TREE_CHAIN (elt_list);
! 	    if (elt_list)
! 	      {
! 		i = TREE_VALUE (elt_list);
! 		gcc_assert (!TREE_CHAIN (elt_list));
! 	      }
! 	  }
  	if (r == NULL || i == NULL)
  	  {
  	    tree zero = convert (TREE_TYPE (type), integer_zero_node);
--- 2792,2800 ----
  	tree r, i;
  
  	/* Extract the real and imaginary parts out of the ctor.  */
! 	gcc_assert (VEC_length (constructor_elt, elts) == 2);
! 	r = VEC_index (constructor_elt, elts, 0)->value;
! 	i = VEC_index (constructor_elt, elts, 1)->value;
  	if (r == NULL || i == NULL)
  	  {
  	    tree zero = convert (TREE_TYPE (type), integer_zero_node);
*************** gimplify_init_constructor (tree *expr_p,
*** 2827,2861 ****
        break;
  
      case VECTOR_TYPE:
!       /* Go ahead and simplify constant constructors to VECTOR_CST.  */
!       if (TREE_CONSTANT (ctor))
! 	{
! 	  tree tem;
  
! 	  /* Even when ctor is constant, it might contain non-*_CST
! 	     elements (e.g. { 1.0/0.0 - 1.0/0.0, 0.0 }) and those don't
! 	     belong into VECTOR_CST nodes.  */
! 	  for (tem = elt_list; tem; tem = TREE_CHAIN (tem))
! 	    if (! CONSTANT_CLASS_P (TREE_VALUE (tem)))
! 	      break;
  
! 	  if (! tem)
! 	    {
! 	      TREE_OPERAND (*expr_p, 1) = build_vector (type, elt_list);
! 	      break;
! 	    }
! 	}
  
!       /* Vector types use CONSTRUCTOR all the way through gimple
! 	 compilation as a general initializer.  */
!       for (; elt_list; elt_list = TREE_CHAIN (elt_list))
! 	{
! 	  enum gimplify_status tret;
! 	  tret = gimplify_expr (&TREE_VALUE (elt_list), pre_p, post_p,
! 				is_gimple_val, fb_rvalue);
! 	  if (tret == GS_ERROR)
! 	    ret = GS_ERROR;
! 	}
        break;
  
      default:
--- 2823,2866 ----
        break;
  
      case VECTOR_TYPE:
!       {
! 	unsigned HOST_WIDE_INT ix;
! 	constructor_elt *ce;
  
! 	/* Go ahead and simplify constant constructors to VECTOR_CST.  */
! 	if (TREE_CONSTANT (ctor))
! 	  {
! 	    bool constant_p = true;
! 	    tree value;
  
! 	    /* Even when ctor is constant, it might contain non-*_CST
! 	      elements (e.g. { 1.0/0.0 - 1.0/0.0, 0.0 }) and those don't
! 	      belong into VECTOR_CST nodes.  */
! 	    FOR_EACH_CONSTRUCTOR_VALUE (elts, ix, value)
! 	      if (!CONSTANT_CLASS_P (value))
! 		{
! 		  constant_p = false;
! 		  break;
! 		}
  
! 	    if (constant_p)
! 	      {
! 		TREE_OPERAND (*expr_p, 1) = build_vector_from_ctor (type, elts);
! 		break;
! 	      }
! 	  }
! 
! 	/* Vector types use CONSTRUCTOR all the way through gimple
! 	  compilation as a general initializer.  */
! 	for (ix = 0; VEC_iterate (constructor_elt, elts, ix, ce); ix++)
! 	  {
! 	    enum gimplify_status tret;
! 	    tret = gimplify_expr (&ce->value, pre_p, post_p,
! 				  is_gimple_val, fb_rvalue);
! 	    if (tret == GS_ERROR)
! 	      ret = GS_ERROR;
! 	  }
!       }
        break;
  
      default:
*************** gimplify_expr (tree *expr_p, tree *pre_p
*** 4159,4168 ****
  	     gimplify any element that has side-effects.  */
  	  if (fallback == fb_none)
  	    {
! 	      for (tmp = CONSTRUCTOR_ELTS (*expr_p); tmp;
! 		   tmp = TREE_CHAIN (tmp))
! 		if (TREE_SIDE_EFFECTS (TREE_VALUE (tmp)))
! 		  gimplify_expr (&TREE_VALUE (tmp), pre_p, post_p,
  				 gimple_test_f, fallback);
  
  	      *expr_p = NULL_TREE;
--- 4164,4177 ----
  	     gimplify any element that has side-effects.  */
  	  if (fallback == fb_none)
  	    {
! 	      unsigned HOST_WIDE_INT ix;
! 	      constructor_elt *ce;
! 	      for (ix = 0;
! 		   VEC_iterate (constructor_elt, CONSTRUCTOR_ELTS (*expr_p),
! 				ix, ce);
! 		   ix++)
! 		if (TREE_SIDE_EFFECTS (ce->value))
! 		  gimplify_expr (&ce->value, pre_p, post_p,
  				 gimple_test_f, fallback);
  
  	      *expr_p = NULL_TREE;
Index: tree-dump.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-dump.c,v
retrieving revision 1.47
diff -c -p -r1.47 tree-dump.c
*** tree-dump.c	5 Jul 2005 16:20:23 -0000	1.47
--- tree-dump.c	9 Jul 2005 15:24:26 -0000
*************** dequeue_and_dump (dump_info_p di)
*** 583,589 ****
        break;
  
      case CONSTRUCTOR:
!       dump_child ("elts", CONSTRUCTOR_ELTS (t));
        break;
  
      case BIND_EXPR:
--- 583,599 ----
        break;
  
      case CONSTRUCTOR:
!       {
! 	unsigned HOST_WIDE_INT cnt;
! 	tree index, value;
! 	dump_int (di, "lngt", VEC_length (constructor_elt,
! 					  CONSTRUCTOR_ELTS (t)));
! 	FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t), cnt, index, value)
! 	  {
! 	    dump_child ("idx", index);
! 	    dump_child ("val", value);
! 	  }
!       }
        break;
  
      case BIND_EXPR:
Index: tree-inline.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-inline.c,v
retrieving revision 1.203
diff -c -p -r1.203 tree-inline.c
*** tree-inline.c	8 Jul 2005 23:36:45 -0000	1.203
--- tree-inline.c	9 Jul 2005 15:24:27 -0000
*************** copy_tree_r (tree *tp, int *walk_subtree
*** 2393,2399 ****
--- 2393,2414 ----
        if (TREE_CODE (*tp) == BIND_EXPR)
  	BIND_EXPR_BLOCK (*tp) = NULL_TREE;
      }
+   else if (code == CONSTRUCTOR)
+     {
+       /* CONSTRUCTOR nodes need special handling because
+          we need to duplicate the vector of elements.  */
+       tree new;
+ 
+       new = copy_node (*tp);
  
+       /* Propagate mudflap marked-ness.  */
+       if (flag_mudflap && mf_marked_p (*tp))
+         mf_mark (new);
+ 
+       CONSTRUCTOR_ELTS (new) = VEC_copy (constructor_elt, gc,
+ 					 CONSTRUCTOR_ELTS (*tp));
+       *tp = new;
+     }
    else if (TREE_CODE_CLASS (code) == tcc_type)
      *walk_subtrees = 0;
    else if (TREE_CODE_CLASS (code) == tcc_declaration)
Index: tree-pretty-print.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-pretty-print.c,v
retrieving revision 2.68
diff -c -p -r2.68 tree-pretty-print.c
*** tree-pretty-print.c	8 Jul 2005 23:36:45 -0000	2.68
--- tree-pretty-print.c	9 Jul 2005 15:24:27 -0000
*************** dump_generic_node (pretty_printer *buffe
*** 778,813 ****
  
      case CONSTRUCTOR:
        {
! 	tree lnode;
  	bool is_struct_init = FALSE;
  	pp_character (buffer, '{');
- 	lnode = CONSTRUCTOR_ELTS (node);
  	if (TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
  	    || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
  	  is_struct_init = TRUE;
! 	while (lnode && lnode != error_mark_node)
  	  {
! 	    tree val;
! 	    if (TREE_PURPOSE (lnode) && is_struct_init)
  	      {
  		pp_character (buffer, '.');
! 		dump_generic_node (buffer, TREE_PURPOSE (lnode), spc, flags, false);
  		pp_string (buffer, "=");
  	      }
- 	    val = TREE_VALUE (lnode);
  	    if (val && TREE_CODE (val) == ADDR_EXPR)
  	      if (TREE_CODE (TREE_OPERAND (val, 0)) == FUNCTION_DECL)
  		val = TREE_OPERAND (val, 0);
  	    if (val && TREE_CODE (val) == FUNCTION_DECL)
- 	      {
  		dump_decl_name (buffer, val, flags);
- 	      }
  	    else
! 	      {
! 		dump_generic_node (buffer, TREE_VALUE (lnode), spc, flags, false);
! 	      }
! 	    lnode = TREE_CHAIN (lnode);
! 	    if (lnode && TREE_CODE (lnode) == TREE_LIST)
  	      {
  		pp_character (buffer, ',');
  		pp_space (buffer);
--- 778,806 ----
  
      case CONSTRUCTOR:
        {
! 	unsigned HOST_WIDE_INT ix;
! 	tree field, val;
  	bool is_struct_init = FALSE;
  	pp_character (buffer, '{');
  	if (TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
  	    || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
  	  is_struct_init = TRUE;
! 	FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (node), ix, field, val)
  	  {
! 	    if (field && is_struct_init)
  	      {
  		pp_character (buffer, '.');
! 		dump_generic_node (buffer, field, spc, flags, false);
  		pp_string (buffer, "=");
  	      }
  	    if (val && TREE_CODE (val) == ADDR_EXPR)
  	      if (TREE_CODE (TREE_OPERAND (val, 0)) == FUNCTION_DECL)
  		val = TREE_OPERAND (val, 0);
  	    if (val && TREE_CODE (val) == FUNCTION_DECL)
  		dump_decl_name (buffer, val, flags);
  	    else
! 		dump_generic_node (buffer, val, spc, flags, false);
! 	    if (ix != VEC_length (constructor_elt, CONSTRUCTOR_ELTS (node)) - 1)
  	      {
  		pp_character (buffer, ',');
  		pp_space (buffer);
Index: tree-sra.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-sra.c,v
retrieving revision 2.66
diff -c -p -r2.66 tree-sra.c
*** tree-sra.c	2 Jul 2005 22:18:24 -0000	2.66
--- tree-sra.c	9 Jul 2005 15:24:28 -0000
*************** generate_element_init_1 (struct sra_elt 
*** 1642,1647 ****
--- 1642,1649 ----
    enum tree_code init_code;
    struct sra_elt *sub;
    tree t;
+   unsigned HOST_WIDE_INT idx;
+   tree value, purpose;
  
    /* We can be passed DECL_INITIAL of a static variable.  It might have a
       conversion, which we strip off here.  */
*************** generate_element_init_1 (struct sra_elt 
*** 1675,1685 ****
        break;
  
      case CONSTRUCTOR:
!       for (t = CONSTRUCTOR_ELTS (init); t ; t = TREE_CHAIN (t))
  	{
- 	  tree purpose = TREE_PURPOSE (t);
- 	  tree value = TREE_VALUE (t);
- 
  	  if (TREE_CODE (purpose) == RANGE_EXPR)
  	    {
  	      tree lower = TREE_OPERAND (purpose, 0);
--- 1677,1684 ----
        break;
  
      case CONSTRUCTOR:
!       FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (init), idx, purpose, value)
  	{
  	  if (TREE_CODE (purpose) == RANGE_EXPR)
  	    {
  	      tree lower = TREE_OPERAND (purpose, 0);
Index: tree-ssa-ccp.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-ccp.c,v
retrieving revision 2.82
diff -c -p -r2.82 tree-ssa-ccp.c
*** tree-ssa-ccp.c	27 Jun 2005 12:17:24 -0000	2.82
--- tree-ssa-ccp.c	9 Jul 2005 15:24:28 -0000
*************** static tree
*** 936,942 ****
  fold_const_aggregate_ref (tree t)
  {
    prop_value_t *value;
!   tree base, ctor, idx, field, elt;
  
    switch (TREE_CODE (t))
      {
--- 936,944 ----
  fold_const_aggregate_ref (tree t)
  {
    prop_value_t *value;
!   tree base, ctor, idx, field;
!   unsigned HOST_WIDE_INT cnt;
!   tree cfield, cval;
  
    switch (TREE_CODE (t))
      {
*************** fold_const_aggregate_ref (tree t)
*** 993,1005 ****
  	}
  
        /* Whoo-hoo!  I'll fold ya baby.  Yeah!  */
!       for (elt = CONSTRUCTOR_ELTS (ctor);
! 	   (elt && !tree_int_cst_equal (TREE_PURPOSE (elt), idx));
! 	   elt = TREE_CHAIN (elt))
! 	;
! 
!       if (elt)
! 	return TREE_VALUE (elt);
        break;
  
      case COMPONENT_REF:
--- 995,1003 ----
  	}
  
        /* Whoo-hoo!  I'll fold ya baby.  Yeah!  */
!       FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield, cval)
! 	if (tree_int_cst_equal (cfield, idx))
! 	  return cval;
        break;
  
      case COMPONENT_REF:
*************** fold_const_aggregate_ref (tree t)
*** 1035,1045 ****
  
        field = TREE_OPERAND (t, 1);
  
!       for (elt = CONSTRUCTOR_ELTS (ctor); elt; elt = TREE_CHAIN (elt))
! 	if (TREE_PURPOSE (elt) == field
  	    /* FIXME: Handle bit-fields.  */
! 	    && ! DECL_BIT_FIELD (TREE_PURPOSE (elt)))
! 	  return TREE_VALUE (elt);
        break;
  
      default:
--- 1033,1043 ----
  
        field = TREE_OPERAND (t, 1);
  
!       FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield, cval)
! 	if (cfield == field
  	    /* FIXME: Handle bit-fields.  */
! 	    && ! DECL_BIT_FIELD (cfield))
! 	  return cval;
        break;
  
      default:
Index: tree-ssa-operands.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-operands.c,v
retrieving revision 2.92
diff -c -p -r2.92 tree-ssa-operands.c
*** tree-ssa-operands.c	30 Jun 2005 22:18:34 -0000	2.92
--- tree-ssa-operands.c	9 Jul 2005 15:24:29 -0000
*************** get_expr_operands (tree stmt, tree *expr
*** 1389,1398 ****
        {
  	/* General aggregate CONSTRUCTORs have been decomposed, but they
  	   are still in use as the COMPLEX_EXPR equivalent for vectors.  */
  
! 	tree t;
! 	for (t = TREE_OPERAND (expr, 0); t ; t = TREE_CHAIN (t))
! 	  get_expr_operands (stmt, &TREE_VALUE (t), opf_none);
  
  	return;
        }
--- 1389,1401 ----
        {
  	/* General aggregate CONSTRUCTORs have been decomposed, but they
  	   are still in use as the COMPLEX_EXPR equivalent for vectors.  */
+ 	constructor_elt *ce;
+ 	unsigned HOST_WIDE_INT idx;
  
! 	for (idx = 0;
! 	     VEC_iterate (constructor_elt, CONSTRUCTOR_ELTS (expr), idx, ce);
! 	     idx++)
! 	  get_expr_operands (stmt, &ce->value, opf_none);
  
  	return;
        }
Index: tree-vect-generic.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-vect-generic.c,v
retrieving revision 2.3
diff -c -p -r2.3 tree-vect-generic.c
*** tree-vect-generic.c	25 Jun 2005 02:01:50 -0000	2.3
--- tree-vect-generic.c	9 Jul 2005 15:24:29 -0000
*************** expand_vector_piecewise (block_stmt_iter
*** 207,213 ****
  			 tree type, tree inner_type,
  			 tree a, tree b, enum tree_code code)
  {
!   tree head, *chain = &head;
    tree part_width = TYPE_SIZE (inner_type);
    tree index = bitsize_int (0);
    int nunits = TYPE_VECTOR_SUBPARTS (type);
--- 207,213 ----
  			 tree type, tree inner_type,
  			 tree a, tree b, enum tree_code code)
  {
!   VEC(constructor_elt,gc) *v;
    tree part_width = TYPE_SIZE (inner_type);
    tree index = bitsize_int (0);
    int nunits = TYPE_VECTOR_SUBPARTS (type);
*************** expand_vector_piecewise (block_stmt_iter
*** 215,229 ****
  	      / tree_low_cst (TYPE_SIZE (TREE_TYPE (type)), 1);
    int i;
  
    for (i = 0; i < nunits;
         i += delta, index = int_const_binop (PLUS_EXPR, index, part_width, 0))
      {
        tree result = f (bsi, inner_type, a, b, index, part_width, code);
!       *chain = tree_cons (NULL_TREE, result, NULL_TREE);
!       chain = &TREE_CHAIN (*chain);
      }
  
!   return build1 (CONSTRUCTOR, type, head);
  }
  
  /* Expand a vector operation to scalars with the freedom to use
--- 215,231 ----
  	      / tree_low_cst (TYPE_SIZE (TREE_TYPE (type)), 1);
    int i;
  
+   v = VEC_alloc(constructor_elt, gc, (nunits + delta - 1) / delta);
    for (i = 0; i < nunits;
         i += delta, index = int_const_binop (PLUS_EXPR, index, part_width, 0))
      {
        tree result = f (bsi, inner_type, a, b, index, part_width, code);
!       constructor_elt *ce = VEC_quick_push (constructor_elt, v, NULL);
!       ce->index = NULL_TREE;
!       ce->value = result;
      }
  
!   return build_constructor (type, v);
  }
  
  /* Expand a vector operation to scalars with the freedom to use
Index: tree-vect-transform.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-vect-transform.c,v
retrieving revision 2.36
diff -c -p -r2.36 tree-vect-transform.c
*** tree-vect-transform.c	6 Jul 2005 02:25:05 -0000	2.36
--- tree-vect-transform.c	9 Jul 2005 15:24:30 -0000
*************** vect_get_vec_def_for_operand (tree op, t
*** 596,602 ****
              t = tree_cons (NULL_TREE, def, t);
            }
  
!         vec_inv = build_constructor (vectype, t);
          return vect_init_vector (stmt, vec_inv);
        }
  
--- 596,603 ----
              t = tree_cons (NULL_TREE, def, t);
            }
  
! 	/* FIXME: use build_constructor directly.  */
!         vec_inv = build_constructor_from_list (vectype, t);
          return vect_init_vector (stmt, vec_inv);
        }
  
*************** get_initial_def_for_reduction (tree stmt
*** 771,777 ****
    if (TREE_CODE (init_val) == INTEGER_CST || TREE_CODE (init_val) == REAL_CST)
      vec = build_vector (vectype, t);
    else
!     vec = build_constructor (vectype, t);
      
    if (!need_epilog_adjust)
      {
--- 772,778 ----
    if (TREE_CODE (init_val) == INTEGER_CST || TREE_CODE (init_val) == REAL_CST)
      vec = build_vector (vectype, t);
    else
!     vec = build_constructor_from_list (vectype, t);
      
    if (!need_epilog_adjust)
      {
Index: tree-vn.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-vn.c,v
retrieving revision 2.12
diff -c -p -r2.12 tree-vn.c
*** tree-vn.c	25 Jun 2005 02:01:52 -0000	2.12
--- tree-vn.c	9 Jul 2005 15:24:30 -0000
*************** set_value_handle (tree e, tree v)
*** 182,188 ****
  {
    if (TREE_CODE (e) == SSA_NAME)
      SSA_NAME_VALUE (e) = v;
!   else if (EXPR_P (e) || DECL_P (e) || TREE_CODE (e) == TREE_LIST)
      get_tree_ann (e)->common.value_handle = v;
    else
      /* Do nothing.  Constants are their own value handles.  */
--- 182,189 ----
  {
    if (TREE_CODE (e) == SSA_NAME)
      SSA_NAME_VALUE (e) = v;
!   else if (EXPR_P (e) || DECL_P (e) || TREE_CODE (e) == TREE_LIST
! 	   || TREE_CODE (e) == CONSTRUCTOR)
      get_tree_ann (e)->common.value_handle = v;
    else
      /* Do nothing.  Constants are their own value handles.  */
*************** get_value_handle (tree expr)
*** 287,293 ****
  
    if (TREE_CODE (expr) == SSA_NAME)
      return SSA_NAME_VALUE (expr);
!   else if (EXPR_P (expr) || DECL_P (expr) || TREE_CODE (expr) == TREE_LIST)
      {
        tree_ann_t ann = tree_ann (expr);
        return ((ann) ? ann->common.value_handle : NULL_TREE);
--- 288,295 ----
  
    if (TREE_CODE (expr) == SSA_NAME)
      return SSA_NAME_VALUE (expr);
!   else if (EXPR_P (expr) || DECL_P (expr) || TREE_CODE (expr) == TREE_LIST
! 	   || TREE_CODE (expr) == CONSTRUCTOR)
      {
        tree_ann_t ann = tree_ann (expr);
        return ((ann) ? ann->common.value_handle : NULL_TREE);
Index: tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.c,v
retrieving revision 1.496
diff -c -p -r1.496 tree.c
*** tree.c	8 Jul 2005 23:36:45 -0000	1.496
--- tree.c	9 Jul 2005 15:24:32 -0000
*************** static const char * const tree_node_kind
*** 93,98 ****
--- 93,99 ----
    "binfos",
    "phi_nodes",
    "ssa names",
+   "constructors",
    "random kinds",
    "lang_decl kinds",
    "lang_type kinds"
*************** tree_code_size (enum tree_code code)
*** 328,333 ****
--- 329,335 ----
  	case STATEMENT_LIST:	return sizeof (struct tree_statement_list);
  	case BLOCK:		return sizeof (struct tree_block);
  	case VALUE_HANDLE:	return sizeof (struct tree_value_handle);
+ 	case CONSTRUCTOR:	return sizeof (struct tree_constructor);
  
  	default:
  	  return lang_hooks.tree_size (code);
*************** make_node_stat (enum tree_code code MEM_
*** 418,424 ****
  	  kind = id_kind;
  	  break;
  
! 	case TREE_VEC:;
  	  kind = vec_kind;
  	  break;
  
--- 420,426 ----
  	  kind = id_kind;
  	  break;
  
! 	case TREE_VEC:
  	  kind = vec_kind;
  	  break;
  
*************** make_node_stat (enum tree_code code MEM_
*** 438,443 ****
--- 440,449 ----
  	  kind = b_kind;
  	  break;
  
+ 	case CONSTRUCTOR:
+ 	  kind = constr_kind;
+ 	  break;
+ 
  	default:
  	  kind = x_kind;
  	  break;
*************** build_vector (tree type, tree vals)
*** 904,930 ****
    return v;
  }
  
  /* Return a new CONSTRUCTOR node whose type is TYPE and whose values
!    are in a list pointed to by VALS.  */
  tree
! build_constructor (tree type, tree vals)
  {
    tree c = make_node (CONSTRUCTOR);
    TREE_TYPE (c) = type;
    CONSTRUCTOR_ELTS (c) = vals;
  
-   /* ??? May not be necessary.  Mirrors what build does.  */
    if (vals)
      {
!       TREE_SIDE_EFFECTS (c) = TREE_SIDE_EFFECTS (vals);
!       TREE_READONLY (c) = TREE_READONLY (vals);
!       TREE_CONSTANT (c) = TREE_CONSTANT (vals);
!       TREE_INVARIANT (c) = TREE_INVARIANT (vals);
      }
  
!   return c;
  }
  
  /* Return a new REAL_CST node whose type is TYPE and value is D.  */
  
  tree
--- 910,981 ----
    return v;
  }
  
+ /* Return a new VECTOR_CST node whose type is TYPE and whose values
+    are extracted from V, a vector of CONSTRUCTOR_ELT.  */
+ 
+ tree
+ build_vector_from_ctor (tree type, VEC(constructor_elt,gc) *v)
+ {
+   tree list = NULL_TREE;
+   unsigned HOST_WIDE_INT idx;
+   tree value;
+ 
+   FOR_EACH_CONSTRUCTOR_VALUE (v, idx, value)
+     list = tree_cons (NULL_TREE, value, list);
+   return build_vector (type, nreverse (list));
+ }
+ 
  /* Return a new CONSTRUCTOR node whose type is TYPE and whose values
!    are in the VEC pointed by VALS.  */
  tree
! build_constructor (tree type, VEC(constructor_elt,gc) *vals)
  {
    tree c = make_node (CONSTRUCTOR);
    TREE_TYPE (c) = type;
    CONSTRUCTOR_ELTS (c) = vals;
+   return c;
+ }
+ 
+ /* Build a CONSTRUCTOR node made of a single initializer, with the specified
+    INDEX and VALUE.  */
+ tree
+ build_constructor_single (tree type, tree index, tree value)
+ {
+   VEC(constructor_elt,gc) *v;
+   constructor_elt *elt;
+ 
+   v = VEC_alloc (constructor_elt, gc, 1);
+   elt = VEC_quick_push (constructor_elt, v, NULL);
+   elt->index = index;
+   elt->value = value;
+ 
+   return build_constructor (type, v);
+ }
+ 
+ 
+ /* Return a new CONSTRUCTOR node whose type is TYPE and whose values
+    are in a list pointed to by VALS.  */
+ tree
+ build_constructor_from_list (tree type, tree vals)
+ {
+   tree t;
+   VEC(constructor_elt,gc) *v = NULL;
  
    if (vals)
      {
!       v = VEC_alloc (constructor_elt, gc, list_length (vals));
!       for (t = vals; t; t = TREE_CHAIN (t))
! 	{
! 	  constructor_elt *elt = VEC_quick_push (constructor_elt, v, NULL);
! 	  elt->index = TREE_PURPOSE (t);
! 	  elt->value = TREE_VALUE (t);
! 	}
      }
  
!   return build_constructor (type, v);
  }
  
+ 
  /* Return a new REAL_CST node whose type is TYPE and value is D.  */
  
  tree
*************** tree_node_structure (tree t)
*** 1951,1956 ****
--- 2002,2008 ----
      case PLACEHOLDER_EXPR:	return TS_COMMON;
      case STATEMENT_LIST:	return TS_STATEMENT_LIST;
      case BLOCK:			return TS_BLOCK;
+     case CONSTRUCTOR:		return TS_CONSTRUCTOR;
      case TREE_BINFO:		return TS_BINFO;
      case VALUE_HANDLE:		return TS_VALUE_HANDLE;
  
*************** simple_cst_equal (tree t1, tree t2)
*** 4321,4328 ****
  			 TREE_STRING_LENGTH (t1)));
  
      case CONSTRUCTOR:
!       return simple_cst_list_equal (CONSTRUCTOR_ELTS (t1),
! 	                            CONSTRUCTOR_ELTS (t2));
  
      case SAVE_EXPR:
        return simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
--- 4373,4393 ----
  			 TREE_STRING_LENGTH (t1)));
  
      case CONSTRUCTOR:
!       {
! 	unsigned HOST_WIDE_INT idx;
! 	VEC(constructor_elt, gc) *v1 = CONSTRUCTOR_ELTS (t1);
! 	VEC(constructor_elt, gc) *v2 = CONSTRUCTOR_ELTS (t2);
! 
! 	if (VEC_length (constructor_elt, v1) != VEC_length (constructor_elt, v2))
! 	  return false;
! 
!         for (idx = 0; idx < VEC_length (constructor_elt, v1); ++idx)
! 	  /* ??? Should we handle also fields here? */
! 	  if (!simple_cst_equal (VEC_index (constructor_elt, v1, idx)->value,
! 				 VEC_index (constructor_elt, v2, idx)->value))
! 	    return false;
! 	return true;
!       }
  
      case SAVE_EXPR:
        return simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
*************** iterative_hash_expr (tree t, hashval_t v
*** 4530,4535 ****
--- 4595,4611 ----
        for (; t; t = TREE_CHAIN (t))
  	val = iterative_hash_expr (TREE_VALUE (t), val);
        return val;
+     case CONSTRUCTOR:
+       {
+ 	unsigned HOST_WIDE_INT idx;
+ 	tree field, value;
+ 	FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t), idx, field, value)
+ 	  {
+ 	    val = iterative_hash_expr (field, val);
+ 	    val = iterative_hash_expr (value, val);
+ 	  }
+ 	return val;
+       }
      case FUNCTION_DECL:
        /* When referring to a built-in FUNCTION_DECL, use the
  	 __builtin__ form.  Otherwise nodes that compare equal
*************** initializer_zerop (tree init)
*** 6402,6415 ****
        return true;
  
      case CONSTRUCTOR:
!       elt = CONSTRUCTOR_ELTS (init);
!       if (elt == NULL_TREE)
! 	return true;
  
!       for (; elt ; elt = TREE_CHAIN (elt))
! 	if (! initializer_zerop (TREE_VALUE (elt)))
! 	  return false;
!       return true;
  
      default:
        return false;
--- 6478,6491 ----
        return true;
  
      case CONSTRUCTOR:
!       {
! 	unsigned HOST_WIDE_INT idx;
  
! 	FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (init), idx, elt)
! 	  if (!initializer_zerop (elt))
! 	    return false;
! 	return true;
!       }
  
      default:
        return false;
*************** walk_tree (tree *tp, walk_tree_fn func, 
*** 7057,7063 ****
  	  WALK_SUBTREE_TAIL (TREE_IMAGPART (*tp));
  
  	case CONSTRUCTOR:
! 	  WALK_SUBTREE_TAIL (CONSTRUCTOR_ELTS (*tp));
  
  	case SAVE_EXPR:
  	  WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, 0));
--- 7133,7148 ----
  	  WALK_SUBTREE_TAIL (TREE_IMAGPART (*tp));
  
  	case CONSTRUCTOR:
! 	  {
! 	    unsigned HOST_WIDE_INT idx;
! 	    constructor_elt *ce;
! 
! 	    for (idx = 0;
! 		 VEC_iterate(constructor_elt, CONSTRUCTOR_ELTS (*tp), idx, ce);
! 		 idx++)
! 	      WALK_SUBTREE (ce->value);
! 	  }
! 	  break;
  
  	case SAVE_EXPR:
  	  WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, 0));
Index: tree.def
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.def,v
retrieving revision 1.120
diff -c -p -r1.120 tree.def
*** tree.def	26 Jun 2005 18:43:05 -0000	1.120
--- tree.def	9 Jul 2005 15:30:30 -0000
*************** DEFTREECODE (FILTER_EXPR, "filter_expr",
*** 435,453 ****
  
  /* Constructor: return an aggregate value made from specified components.
     In C, this is used only for structure and array initializers.
!    The operand is a list of component values made out of a chain of
!    TREE_LIST nodes.
  
     For ARRAY_TYPE:
!    The TREE_PURPOSE of each node is the corresponding index.
!    If the TREE_PURPOSE is a RANGE_EXPR, it is a short-hand for many nodes,
!    one for each index in the range.  (If the corresponding TREE_VALUE
     has side-effects, they are evaluated once for each element.  Wrap the
     value in a SAVE_EXPR if you want to evaluate side effects only once.)
  
     For RECORD_TYPE, UNION_TYPE, or QUAL_UNION_TYPE:
!    The TREE_PURPOSE of each node is a FIELD_DECL.  */
! DEFTREECODE (CONSTRUCTOR, "constructor", tcc_expression, 1)
  
  /* The expression types are mostly straightforward, with the fourth argument
     of DEFTREECODE saying how many operands there are.
--- 435,453 ----
  
  /* Constructor: return an aggregate value made from specified components.
     In C, this is used only for structure and array initializers.
!    The operand is a sequence of component values made out of a VEC of
!    struct constructor_elt.
  
     For ARRAY_TYPE:
!    The field INDEX of each constructor_elt is the corresponding index.
!    If the index is a RANGE_EXPR, it is a short-hand for many nodes,
!    one for each index in the range.  (If the corresponding field VALUE
     has side-effects, they are evaluated once for each element.  Wrap the
     value in a SAVE_EXPR if you want to evaluate side effects only once.)
  
     For RECORD_TYPE, UNION_TYPE, or QUAL_UNION_TYPE:
!    The field INDEX of each node is a FIELD_DECL.  */
! DEFTREECODE (CONSTRUCTOR, "constructor", tcc_exceptional, 0)
  
  /* The expression types are mostly straightforward, with the fourth argument
     of DEFTREECODE saying how many operands there are.
Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.745
diff -c -p -r1.745 tree.h
*** tree.h	8 Jul 2005 23:36:46 -0000	1.745
--- tree.h	9 Jul 2005 15:24:34 -0000
*************** struct tree_vec GTY(())
*** 1190,1195 ****
--- 1190,1246 ----
    tree GTY ((length ("TREE_VEC_LENGTH ((tree)&%h)"))) a[1];
  };
  
+ /* In a CONSTRUCTOR node.  */
+ #define CONSTRUCTOR_ELTS(NODE) (CONSTRUCTOR_CHECK (NODE)->constructor.elts)
+ 
+ /* Iterate through the vector V of CONSTRUCTOR_ELT elements, yielding the
+    value of each element (stored within VAL). IX must be a scratch variable
+    of unsigned integer type.  */
+ #define FOR_EACH_CONSTRUCTOR_VALUE(V, IX, VAL) \
+   for (IX = 0; (IX >= VEC_length (constructor_elt, V)) \
+ 	       ? false \
+ 	       : ((VAL = VEC_index (constructor_elt, V, IX)->value), \
+ 	       true); \
+        (IX)++)
+ 
+ /* Iterate through the vector V of CONSTRUCTOR_ELT elements, yielding both
+    the value of each element (stored within VAL) and its index (stored
+    within INDEX). IX must be a scratch variable of unsigned integer type.  */
+ #define FOR_EACH_CONSTRUCTOR_ELT(V, IX, INDEX, VAL) \
+   for (IX = 0; (IX >= VEC_length (constructor_elt, V)) \
+ 	       ? false \
+ 	       : ((VAL = VEC_index (constructor_elt, V, IX)->value), \
+ 		  (INDEX = VEC_index (constructor_elt, V, IX)->index), \
+ 	       true); \
+        (IX)++)
+ 
+ /* Append a new constructor element to V, with the specified INDEX and VAL.  */
+ #define CONSTRUCTOR_APPEND_ELT(V, INDEX, VALUE) \
+   do { \
+     constructor_elt *_ce___ = VEC_safe_push (constructor_elt, gc, V, NULL); \
+     _ce___->index = INDEX; \
+     _ce___->value = VALUE; \
+   } while (0)
+ 
+ /* A single element of a CONSTRUCTOR. VALUE holds the actual value of the
+    element. INDEX can optionally design the position of VALUE: in arrays,
+    it is the index where VALUE has to be placed; in structures, it is the
+    FIELD_DECL of the member.  */
+ typedef struct constructor_elt_d GTY(())
+ {
+   tree index;
+   tree value;
+ } constructor_elt;
+ 
+ DEF_VEC_O(constructor_elt);
+ DEF_VEC_ALLOC_O(constructor_elt,gc);
+ 
+ struct tree_constructor GTY(())
+ {
+   struct tree_common common;
+   VEC(constructor_elt,gc) *elts;
+ };
+ 
  /* Define fields and accessors for some nodes that represent expressions.  */
  
  /* Nonzero if NODE is an empty statement (NOP_EXPR <0>).  */
*************** struct tree_vec GTY(())
*** 1197,1205 ****
  				 && VOID_TYPE_P (TREE_TYPE (NODE)) \
  				 && integer_zerop (TREE_OPERAND (NODE, 0)))
  
- /* In a CONSTRUCTOR node.  */
- #define CONSTRUCTOR_ELTS(NODE) TREE_OPERAND_CHECK_CODE (NODE, CONSTRUCTOR, 0)
- 
  /* In ordinary expression nodes.  */
  #define TREE_OPERAND(NODE, I) TREE_OPERAND_CHECK (NODE, I)
  #define TREE_COMPLEXITY(NODE) (EXPR_CHECK (NODE)->exp.complexity)
--- 1248,1253 ----
*************** struct tree_value_handle GTY(())
*** 2724,2731 ****
    unsigned int id;
  };
  
- 
- 
  /* Define the overall contents of a tree node.
     It may be any of the structures declared above
     for various types of node.  */
--- 2772,2777 ----
*************** union tree_node GTY ((ptr_alias (union l
*** 2763,2768 ****
--- 2809,2815 ----
    struct tree_binfo GTY ((tag ("TS_BINFO"))) binfo;
    struct tree_statement_list GTY ((tag ("TS_STATEMENT_LIST"))) stmt_list;
    struct tree_value_handle GTY ((tag ("TS_VALUE_HANDLE"))) value_handle;
+   struct tree_constructor GTY ((tag ("TS_CONSTRUCTOR"))) constructor;
  };
  
  /* Standard named or nameless data types of the C compiler.  */
*************** extern tree build_int_cst_type (tree, HO
*** 3103,3109 ****
  extern tree build_int_cstu (tree, unsigned HOST_WIDE_INT);
  extern tree build_int_cst_wide (tree, unsigned HOST_WIDE_INT, HOST_WIDE_INT);
  extern tree build_vector (tree, tree);
! extern tree build_constructor (tree, tree);
  extern tree build_real_from_int_cst (tree, tree);
  extern tree build_complex (tree, tree, tree);
  extern tree build_string (int, const char *);
--- 3150,3159 ----
  extern tree build_int_cstu (tree, unsigned HOST_WIDE_INT);
  extern tree build_int_cst_wide (tree, unsigned HOST_WIDE_INT, HOST_WIDE_INT);
  extern tree build_vector (tree, tree);
! extern tree build_vector_from_ctor (tree, VEC(constructor_elt,gc) *);
! extern tree build_constructor (tree, VEC(constructor_elt,gc) *);
! extern tree build_constructor_single (tree, tree, tree);
! extern tree build_constructor_from_list (tree, tree);
  extern tree build_real_from_int_cst (tree, tree);
  extern tree build_complex (tree, tree, tree);
  extern tree build_string (int, const char *);
*************** typedef enum
*** 4080,4085 ****
--- 4130,4136 ----
    binfo_kind,
    phi_kind,
    ssa_name_kind,
+   constr_kind,
    x_kind,
    lang_decl,
    lang_type,
Index: treestruct.def
===================================================================
RCS file: /cvs/gcc/gcc/gcc/treestruct.def,v
retrieving revision 2.1
diff -c -p -r2.1 treestruct.def
*** treestruct.def	8 Jul 2005 23:36:47 -0000	2.1
--- treestruct.def	9 Jul 2005 15:24:34 -0000
*************** DEFTREESTRUCT(TS_BLOCK, "block")
*** 58,60 ****
--- 58,61 ----
  DEFTREESTRUCT(TS_BINFO, "binfo")
  DEFTREESTRUCT(TS_STATEMENT_LIST, "statement list")
  DEFTREESTRUCT(TS_VALUE_HANDLE, "value handle")
+ DEFTREESTRUCT(TS_CONSTRUCTOR, "constructor")
Index: varasm.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/varasm.c,v
retrieving revision 1.520
diff -c -p -r1.520 varasm.c
*** varasm.c	3 Jul 2005 14:14:28 -0000	1.520
--- varasm.c	9 Jul 2005 15:24:35 -0000
*************** const_hash_1 (const tree exp)
*** 2400,2412 ****
  
      case CONSTRUCTOR:
        {
! 	tree link;
  	
  	hi = 5 + int_size_in_bytes (TREE_TYPE (exp));
  	
! 	for (link = CONSTRUCTOR_ELTS (exp); link; link = TREE_CHAIN (link))
! 	  if (TREE_VALUE (link))
! 	    hi = hi * 603 + const_hash_1 (TREE_VALUE (link));
  	
  	return hi;
        }
--- 2400,2413 ----
  
      case CONSTRUCTOR:
        {
! 	unsigned HOST_WIDE_INT idx;
! 	tree value;
  	
  	hi = 5 + int_size_in_bytes (TREE_TYPE (exp));
  	
! 	FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (exp), idx, value)
! 	  if (value)
! 	    hi = hi * 603 + const_hash_1 (value);
  	
  	return hi;
        }
*************** compare_constant (const tree t1, const t
*** 2517,2523 ****
  
      case CONSTRUCTOR:
        {
! 	tree l1, l2;
  	
  	typecode = TREE_CODE (TREE_TYPE (t1));
  	if (typecode != TREE_CODE (TREE_TYPE (t2)))
--- 2518,2525 ----
  
      case CONSTRUCTOR:
        {
! 	VEC(constructor_elt, gc) *v1, *v2;
! 	unsigned HOST_WIDE_INT idx;
  	
  	typecode = TREE_CODE (TREE_TYPE (t1));
  	if (typecode != TREE_CODE (TREE_TYPE (t2)))
*************** compare_constant (const tree t1, const t
*** 2540,2567 ****
  	      return 0;
  	  }
  
! 	for (l1 = CONSTRUCTOR_ELTS (t1), l2 = CONSTRUCTOR_ELTS (t2);
! 	     l1 && l2;
! 	     l1 = TREE_CHAIN (l1), l2 = TREE_CHAIN (l2))
  	  {
  	    /* Check that each value is the same...  */
! 	    if (! compare_constant (TREE_VALUE (l1), TREE_VALUE (l2)))
  	      return 0;
  	    /* ... and that they apply to the same fields!  */
  	    if (typecode == ARRAY_TYPE)
  	      {
! 		if (! compare_constant (TREE_PURPOSE (l1),
! 					TREE_PURPOSE (l2)))
  		  return 0;
  	      }
  	    else
  	      {
! 		if (TREE_PURPOSE (l1) != TREE_PURPOSE (l2))
  		  return 0;
  	      }
  	  }
  	
! 	return l1 == NULL_TREE && l2 == NULL_TREE;
        }
  
      case ADDR_EXPR:
--- 2542,2575 ----
  	      return 0;
  	  }
  
! 	v1 = CONSTRUCTOR_ELTS (t1);
! 	v2 = CONSTRUCTOR_ELTS (t2);
! 	if (VEC_length (constructor_elt, v1)
! 	    != VEC_length (constructor_elt, v2))
! 	    return 0;
! 
! 	for (idx = 0; idx < VEC_length (constructor_elt, v1); ++idx)
  	  {
+ 	    constructor_elt *c1 = VEC_index (constructor_elt, v1, idx);
+ 	    constructor_elt *c2 = VEC_index (constructor_elt, v2, idx);
+ 
  	    /* Check that each value is the same...  */
! 	    if (!compare_constant (c1->value, c2->value))
  	      return 0;
  	    /* ... and that they apply to the same fields!  */
  	    if (typecode == ARRAY_TYPE)
  	      {
! 		if (!compare_constant (c1->index, c2->index))
  		  return 0;
  	      }
  	    else
  	      {
! 		if (c1->index != c2->index)
  		  return 0;
  	      }
  	  }
  	
! 	return 1;
        }
  
      case ADDR_EXPR:
*************** copy_constant (tree exp)
*** 2645,2657 ****
      case CONSTRUCTOR:
        {
  	tree copy = copy_node (exp);
! 	tree list = copy_list (CONSTRUCTOR_ELTS (exp));
! 	tree tail;
! 
! 	CONSTRUCTOR_ELTS (copy) = list;
! 	for (tail = list; tail; tail = TREE_CHAIN (tail))
! 	  TREE_VALUE (tail) = copy_constant (TREE_VALUE (tail));
! 
  	return copy;
        }
  
--- 2653,2671 ----
      case CONSTRUCTOR:
        {
  	tree copy = copy_node (exp);
! 	VEC(constructor_elt, gc) *v;
! 	unsigned HOST_WIDE_INT idx;
! 	tree purpose, value;
! 	
! 	v = VEC_alloc(constructor_elt, gc, VEC_length(constructor_elt,
! 						      CONSTRUCTOR_ELTS (exp)));
! 	FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (exp), idx, purpose, value)
! 	  {
! 	    constructor_elt *ce = VEC_quick_push (constructor_elt, v, NULL);
! 	    ce->index = purpose;
! 	    ce->value = copy_constant (value);
! 	  }
! 	CONSTRUCTOR_ELTS (copy) = v;
  	return copy;
        }
  
*************** compute_reloc_for_constant (tree exp)
*** 3476,3485 ****
        break;
  
      case CONSTRUCTOR:
!       for (tem = CONSTRUCTOR_ELTS (exp); tem; tem = TREE_CHAIN (tem))
! 	if (TREE_VALUE (tem) != 0)
! 	  reloc |= compute_reloc_for_constant (TREE_VALUE (tem));
! 
        break;
  
      default:
--- 3490,3501 ----
        break;
  
      case CONSTRUCTOR:
!       {
! 	unsigned HOST_WIDE_INT idx;
! 	FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (exp), idx, tem)
! 	  if (tem != 0)
! 	    reloc |= compute_reloc_for_constant (tem);
!       }
        break;
  
      default:
*************** output_addressed_constants (tree exp)
*** 3533,3542 ****
        break;
  
      case CONSTRUCTOR:
!       for (tem = CONSTRUCTOR_ELTS (exp); tem; tem = TREE_CHAIN (tem))
! 	if (TREE_VALUE (tem) != 0)
! 	  output_addressed_constants (TREE_VALUE (tem));
! 
        break;
  
      default:
--- 3549,3560 ----
        break;
  
      case CONSTRUCTOR:
!       {
! 	unsigned HOST_WIDE_INT idx;
! 	FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (exp), idx, tem)
! 	  if (tem != 0)
! 	    output_addressed_constants (tem);
!       }
        break;
  
      default:
*************** initializer_constant_valid_p (tree value
*** 3567,3582 ****
        if ((TREE_CODE (TREE_TYPE (value)) == UNION_TYPE
  	   || TREE_CODE (TREE_TYPE (value)) == RECORD_TYPE)
  	  && TREE_CONSTANT (value)
! 	  && CONSTRUCTOR_ELTS (value))
  	{
  	  tree elt;
  	  bool absolute = true;
  
! 	  for (elt = CONSTRUCTOR_ELTS (value); elt; elt = TREE_CHAIN (elt))
  	    {
  	      tree reloc;
! 	      value = TREE_VALUE (elt);
! 	      reloc = initializer_constant_valid_p (value, TREE_TYPE (value));
  	      if (!reloc)
  		return NULL_TREE;
  	      if (reloc != null_pointer_node)
--- 3585,3600 ----
        if ((TREE_CODE (TREE_TYPE (value)) == UNION_TYPE
  	   || TREE_CODE (TREE_TYPE (value)) == RECORD_TYPE)
  	  && TREE_CONSTANT (value)
! 	  && !VEC_empty (constructor_elt, CONSTRUCTOR_ELTS (value)))
  	{
+ 	  unsigned HOST_WIDE_INT idx;
  	  tree elt;
  	  bool absolute = true;
  
! 	  FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (value), idx, elt)
  	    {
  	      tree reloc;
! 	      reloc = initializer_constant_valid_p (elt, TREE_TYPE (elt));
  	      if (!reloc)
  		return NULL_TREE;
  	      if (reloc != null_pointer_node)
*************** output_constant (tree exp, unsigned HOST
*** 3832,3838 ****
  
    /* Allow a constructor with no elements for any data type.
       This means to fill the space with zeros.  */
!   if (TREE_CODE (exp) == CONSTRUCTOR && CONSTRUCTOR_ELTS (exp) == 0)
      {
        assemble_zeros (size);
        return;
--- 3850,3857 ----
  
    /* Allow a constructor with no elements for any data type.
       This means to fill the space with zeros.  */
!   if (TREE_CODE (exp) == CONSTRUCTOR
!       && VEC_empty (constructor_elt, CONSTRUCTOR_ELTS (exp)))
      {
        assemble_zeros (size);
        return;
*************** static unsigned HOST_WIDE_INT
*** 3942,3947 ****
--- 3961,3968 ----
  array_size_for_constructor (tree val)
  {
    tree max_index, i;
+   unsigned HOST_WIDE_INT cnt;
+   tree index, value;
  
    /* This code used to attempt to handle string constants that are not
       arrays of single-bytes, but nothing else does, so there's no point in
*************** array_size_for_constructor (tree val)
*** 3950,3959 ****
      return TREE_STRING_LENGTH (val);
  
    max_index = NULL_TREE;
!   for (i = CONSTRUCTOR_ELTS (val); i; i = TREE_CHAIN (i))
      {
-       tree index = TREE_PURPOSE (i);
- 
        if (TREE_CODE (index) == RANGE_EXPR)
  	index = TREE_OPERAND (index, 1);
        if (max_index == NULL_TREE || tree_int_cst_lt (max_index, index))
--- 3971,3978 ----
      return TREE_STRING_LENGTH (val);
  
    max_index = NULL_TREE;
!   FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (val), cnt, index, value)
      {
        if (TREE_CODE (index) == RANGE_EXPR)
  	index = TREE_OPERAND (index, 1);
        if (max_index == NULL_TREE || tree_int_cst_lt (max_index, index))
*************** output_constructor (tree exp, unsigned H
*** 3983,3989 ****
  		    unsigned int align)
  {
    tree type = TREE_TYPE (exp);
!   tree link, field = 0;
    tree min_index = 0;
    /* Number of bytes output or skipped so far.
       In other words, current position within the constructor.  */
--- 4002,4008 ----
  		    unsigned int align)
  {
    tree type = TREE_TYPE (exp);
!   tree field = 0;
    tree min_index = 0;
    /* Number of bytes output or skipped so far.
       In other words, current position within the constructor.  */
*************** output_constructor (tree exp, unsigned H
*** 3991,3996 ****
--- 4010,4017 ----
    /* Nonzero means BYTE contains part of a byte, to be output.  */
    int byte_buffer_in_use = 0;
    int byte = 0;
+   unsigned HOST_WIDE_INT cnt;
+   constructor_elt *ce;
  
    gcc_assert (HOST_BITS_PER_WIDE_INT >= BITS_PER_UNIT);
  
*************** output_constructor (tree exp, unsigned H
*** 4010,4032 ****
       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),
!        field = field ? TREE_CHAIN (field) : 0)
      {
!       tree val = TREE_VALUE (link);
        tree index = 0;
  
        /* The element in a union constructor specifies the proper field
  	 or index.  */
        if ((TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE
  	   || TREE_CODE (type) == QUAL_UNION_TYPE)
! 	  && TREE_PURPOSE (link) != 0)
! 	field = TREE_PURPOSE (link);
  
        else if (TREE_CODE (type) == ARRAY_TYPE)
! 	index = TREE_PURPOSE (link);
  
  #ifdef ASM_COMMENT_START
        if (field && flag_verbose_asm)
--- 4031,4052 ----
       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 (cnt = 0;
!        VEC_iterate (constructor_elt, CONSTRUCTOR_ELTS (exp), cnt, ce);
!        cnt++, field = field ? TREE_CHAIN (field) : 0)
      {
!       tree val = ce->value;
        tree index = 0;
  
        /* The element in a union constructor specifies the proper field
  	 or index.  */
        if ((TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE
  	   || TREE_CODE (type) == QUAL_UNION_TYPE)
! 	  && ce->index != 0)
! 	field = ce->index;
  
        else if (TREE_CODE (type) == ARRAY_TYPE)
! 	index = ce->index;
  
  #ifdef ASM_COMMENT_START
        if (field && flag_verbose_asm)
*************** output_constructor (tree exp, unsigned H
*** 4089,4094 ****
--- 4109,4115 ----
  	     if each element has the proper size.  */
  	  if ((field != 0 || index != 0) && pos != total_bytes)
  	    {
+ 	      gcc_assert (pos >= total_bytes);
  	      assemble_zeros (pos - total_bytes);
  	      total_bytes = pos;
  	    }
*************** output_constructor (tree exp, unsigned H
*** 4164,4169 ****
--- 4185,4191 ----
  	      /* If still not at proper byte, advance to there.  */
  	      if (next_offset / BITS_PER_UNIT != total_bytes)
  		{
+ 		  gcc_assert (next_offset / BITS_PER_UNIT >= total_bytes);
  		  assemble_zeros (next_offset / BITS_PER_UNIT - total_bytes);
  		  total_bytes = next_offset / BITS_PER_UNIT;
  		}
Index: vec.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/vec.h,v
retrieving revision 2.30
diff -c -p -r2.30 vec.h
*** vec.h	25 Jun 2005 02:02:01 -0000	2.30
--- vec.h	9 Jul 2005 15:24:36 -0000
*************** Software Foundation, 51 Franklin Street,
*** 147,152 ****
--- 147,161 ----
  
  #define VEC_length(T,V)	(VEC_OP(T,base,length)(VEC_BASE(V)))
  
+ 
+ /* Check if vector is empty
+    int VEC_T_empty(const VEC(T) *v);
+ 
+    Return non-zero if V is an empty vector (or V is NULL), zero otherwise. */
+ 
+ #define VEC_empty(T,V)	(VEC_length (T,V) == 0)
+ 
+ 
  /* Get the final element of the vector.
     T VEC_T_last(VEC(T) *v); // Integer
     T VEC_T_last(VEC(T) *v); // Pointer
*************** Software Foundation, 51 Franklin Street,
*** 205,210 ****
--- 214,227 ----
  #define VEC_embedded_size(T,N)	 (VEC_OP(T,base,embedded_size)(N))
  #define VEC_embedded_init(T,O,N) (VEC_OP(T,base,embedded_init)(VEC_BASE(O),N))
  
+ /* Copy a vector.
+    VEC(T,A) *VEC_T_A_copy(VEC(T) *);
+ 
+    Copy the live elements of a vector into a new vector.  The new and
+    old vectors need not be allocated by the same mechanim.  */
+ 
+ #define VEC_copy(T,A,V) (VEC_OP(T,A,copy)(VEC_BASE(V) MEM_STAT_INFO))
+ 
  /* Determine if a vector has additional capacity.
     
     int VEC_T_space (VEC(T) *v,int reserve)
*************** static inline void VEC_OP (T,A,free)				
*** 667,672 ****
--- 684,706 ----
    *vec_ = NULL;								  \
  }									  \
  									  \
+ static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \
+ {									  \
+   size_t len_ = vec_ ? vec_->num : 0;					  \
+   VEC (T,A) *new_vec_ = NULL;						  \
+ 									  \
+   if (len_)								  \
+     {									  \
+       /* We must request exact size allocation, hence the negation. */	  \
+       new_vec_ = (VEC (T,A) *)(vec_##A##_p_reserve			  \
+ 			       (NULL, -len_ PASS_MEM_STAT));		  \
+ 									  \
+       new_vec_->base.num = len_;					  \
+       memcpy (new_vec_->base.vec, vec_->vec, sizeof (T) * len_);	  \
+     }									  \
+   return new_vec_;							  \
+ }									  \
+ 									  \
  static inline int VEC_OP (T,A,reserve)	       				  \
       (VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL)		  \
  {									  \
*************** static inline VEC(T,A) *VEC_OP (T,A,allo
*** 895,900 ****
--- 929,953 ----
                                             PASS_MEM_STAT);		  \
  }									  \
  									  \
+ static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \
+ {									  \
+   size_t len_ = vec_ ? vec_->num : 0;					  \
+   VEC (T,A) *new_vec_ = NULL;						  \
+ 									  \
+   if (len_)								  \
+     {									  \
+       /* We must request exact size allocation, hence the negation. */	  \
+       new_vec_ = (VEC (T,A) *)(vec_##A##_o_reserve			  \
+ 			       (NULL, -len_,				  \
+ 				offsetof (VEC(T,A),base.vec), sizeof (T)  \
+ 				PASS_MEM_STAT));			  \
+ 									  \
+       new_vec_->base.num = len_;					  \
+       memcpy (new_vec_->base.vec, vec_->vec, sizeof (T) * len_);	  \
+     }									  \
+   return new_vec_;							  \
+ }									  \
+ 									  \
  static inline void VEC_OP (T,A,free)					  \
       (VEC(T,A) **vec_)							  \
  {									  \
Index: ada/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ada/decl.c,v
retrieving revision 1.75
diff -c -p -r1.75 decl.c
*** ada/decl.c	7 Jul 2005 09:41:56 -0000	1.75
--- ada/decl.c	9 Jul 2005 15:24:38 -0000
*************** gnat_to_gnu_entity (Entity_Id gnat_entit
*** 940,955 ****
  		    gnu_alloc_type
  		      = TREE_TYPE (TREE_CHAIN (TYPE_FIELDS (gnu_alloc_type)));
  
!                    if (TREE_CODE (gnu_expr) == CONSTRUCTOR
!                        &&
!                        TREE_CHAIN (CONSTRUCTOR_ELTS (gnu_expr)) == NULL_TREE)
!                      gnu_expr = 0;
!                    else
!                      gnu_expr
!                        = build_component_ref
!                          (gnu_expr, NULL_TREE,
!                           TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (gnu_expr))),
! 			  false);
  		  }
  
  		if (TREE_CODE (TYPE_SIZE_UNIT (gnu_alloc_type)) == INTEGER_CST
--- 940,955 ----
  		    gnu_alloc_type
  		      = TREE_TYPE (TREE_CHAIN (TYPE_FIELDS (gnu_alloc_type)));
  
! 		    if (TREE_CODE (gnu_expr) == CONSTRUCTOR
! 			&& VEC_length (constructor_elt,
! 				       CONSTRUCTOR_ELTS (gnu_expr)) == 1)
! 		      gnu_expr = 0;
! 		    else
! 		      gnu_expr
! 			= build_component_ref
! 			  (gnu_expr, NULL_TREE,
! 			  TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (gnu_expr))),
! 			      false);
  		  }
  
  		if (TREE_CODE (TYPE_SIZE_UNIT (gnu_alloc_type)) == INTEGER_CST
Index: ada/misc.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ada/misc.c,v
retrieving revision 1.106
diff -c -p -r1.106 misc.c
*** ada/misc.c	4 Jul 2005 13:27:09 -0000	1.106
--- ada/misc.c	9 Jul 2005 15:24:39 -0000
*************** gnat_init_options (unsigned int argc, co
*** 339,344 ****
--- 339,346 ----
    /* Uninitialized really means uninitialized in Ada.  */
    flag_zero_initialized_in_bss = 0;
  
+   flag_wrapv = 1;
+ 
    return CL_Ada;
  }
  
Index: ada/trans.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ada/trans.c,v
retrieving revision 1.100
diff -c -p -r1.100 trans.c
*** ada/trans.c	4 Jul 2005 13:27:17 -0000	1.100
--- ada/trans.c	9 Jul 2005 15:24:41 -0000
*************** extract_values (tree values, tree record
*** 5625,5631 ****
        else if (DECL_INTERNAL_P (field))
  	{
  	  value = extract_values (values, TREE_TYPE (field));
! 	  if (TREE_CODE (value) == CONSTRUCTOR && !CONSTRUCTOR_ELTS (value))
  	    value = 0;
  	}
        else
--- 5625,5632 ----
        else if (DECL_INTERNAL_P (field))
  	{
  	  value = extract_values (values, TREE_TYPE (field));
! 	  if (TREE_CODE (value) == CONSTRUCTOR
! 	      && VEC_empty (constructor_elt, CONSTRUCTOR_ELTS (value)))
  	    value = 0;
  	}
        else
Index: ada/utils.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ada/utils.c,v
retrieving revision 1.98
diff -c -p -r1.98 utils.c
*** ada/utils.c	8 Jul 2005 23:36:50 -0000	1.98
--- ada/utils.c	9 Jul 2005 15:24:42 -0000
*************** convert (tree type, tree expr)
*** 2702,2710 ****
        /* If we have just converted to this padded type, just get
  	 the inner expression.  */
        if (TREE_CODE (expr) == CONSTRUCTOR
! 	  && CONSTRUCTOR_ELTS (expr)
! 	  && TREE_PURPOSE (CONSTRUCTOR_ELTS (expr)) == TYPE_FIELDS (etype))
! 	return TREE_VALUE (CONSTRUCTOR_ELTS (expr));
        else
  	return convert (type,
  			build_component_ref (expr, NULL_TREE,
--- 2702,2711 ----
        /* If we have just converted to this padded type, just get
  	 the inner expression.  */
        if (TREE_CODE (expr) == CONSTRUCTOR
! 	  && !VEC_empty (constructor_elt, CONSTRUCTOR_ELTS (expr))
! 	  && VEC_index (constructor_elt, CONSTRUCTOR_ELTS (expr), 0)->index
! 	     == TYPE_FIELDS (etype))
! 	return VEC_index (constructor_elt, CONSTRUCTOR_ELTS (expr), 0)->value;
        else
  	return convert (type,
  			build_component_ref (expr, NULL_TREE,
*************** remove_conversions (tree exp, bool true_
*** 3024,3030 ****
        if (true_address
  	  && TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
  	  && TYPE_JUSTIFIED_MODULAR_P (TREE_TYPE (exp)))
! 	return remove_conversions (TREE_VALUE (CONSTRUCTOR_ELTS (exp)), true);
        break;
  
      case COMPONENT_REF:
--- 3025,3033 ----
        if (true_address
  	  && TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
  	  && TYPE_JUSTIFIED_MODULAR_P (TREE_TYPE (exp)))
! 	return remove_conversions (VEC_index (constructor_elt,
! 					      CONSTRUCTOR_ELTS (exp), 0)->value,
! 				   true);
        break;
  
      case COMPONENT_REF:
Index: ada/utils2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ada/utils2.c,v
retrieving revision 1.49
diff -c -p -r1.49 utils2.c
*** ada/utils2.c	1 Jul 2005 01:29:07 -0000	1.49
--- ada/utils2.c	9 Jul 2005 15:24:43 -0000
*************** contains_save_expr_p (tree exp)
*** 263,275 ****
        return contains_save_expr_p (TREE_OPERAND (exp, 0));
  
      case CONSTRUCTOR:
!       return (CONSTRUCTOR_ELTS (exp)
! 	      && contains_save_expr_p (CONSTRUCTOR_ELTS (exp)));
  
!     case TREE_LIST:
!       return (contains_save_expr_p (TREE_VALUE (exp))
! 	      || (TREE_CHAIN (exp)
! 		  && contains_save_expr_p (TREE_CHAIN (exp))));
  
      default:
        return false;
--- 263,277 ----
        return contains_save_expr_p (TREE_OPERAND (exp, 0));
  
      case CONSTRUCTOR:
!       {
! 	tree value;
! 	unsigned HOST_WIDE_INT ix;
  
! 	FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (exp), ix, value)
! 	  if (contains_save_expr_p (value))
! 	    return true;
! 	return false;
!       }
  
      default:
        return false;
*************** build_binary_op (enum tree_code op_code,
*** 884,891 ****
  	 just compare the data pointer.  */
        else if (TYPE_FAT_POINTER_P (left_base_type)
  	       && TREE_CODE (right_operand) == CONSTRUCTOR
! 	       && integer_zerop (TREE_VALUE
! 				 (CONSTRUCTOR_ELTS (right_operand))))
  	{
  	  right_operand = build_component_ref (left_operand, NULL_TREE,
  					       TYPE_FIELDS (left_base_type),
--- 886,894 ----
  	 just compare the data pointer.  */
        else if (TYPE_FAT_POINTER_P (left_base_type)
  	       && TREE_CODE (right_operand) == CONSTRUCTOR
! 	       && integer_zerop (VEC_index (constructor_elt,
! 					    CONSTRUCTOR_ELTS (right_operand),
! 					    0)->value))
  	{
  	  right_operand = build_component_ref (left_operand, NULL_TREE,
  					       TYPE_FIELDS (left_base_type),
*************** build_unary_op (enum tree_code op_code, 
*** 1138,1146 ****
  	     a pointer to our type.  */
  	  if (TREE_CODE (type) == RECORD_TYPE && TYPE_IS_PADDING_P (type))
  	    {
  	      result
! 		= build_unary_op (ADDR_EXPR, NULL_TREE,
! 				  TREE_VALUE (CONSTRUCTOR_ELTS (operand)));
  	      result = convert (build_pointer_type (TREE_TYPE (operand)),
  				result);
  	      break;
--- 1141,1151 ----
  	     a pointer to our type.  */
  	  if (TREE_CODE (type) == RECORD_TYPE && TYPE_IS_PADDING_P (type))
  	    {
+ 	      result = VEC_index (constructor_elt,
+ 				  CONSTRUCTOR_ELTS (operand),
+ 				  0)->value;
  	      result
! 		= build_unary_op (ADDR_EXPR, NULL_TREE, result);
  	      result = convert (build_pointer_type (TREE_TYPE (operand)),
  				result);
  	      break;
*************** gnat_build_constructor (tree type, tree 
*** 1501,1507 ****
  	}
      }
  
!   result = build_constructor (type, list);
    TREE_CONSTANT (result) = TREE_INVARIANT (result)
      = TREE_STATIC (result) = allconstant;
    TREE_SIDE_EFFECTS (result) = side_effects;
--- 1506,1512 ----
  	}
      }
  
!   result = build_constructor_from_list (type, list);
    TREE_CONSTANT (result) = TREE_INVARIANT (result)
      = TREE_STATIC (result) = allconstant;
    TREE_SIDE_EFFECTS (result) = side_effects;
Index: cp/call.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/call.c,v
retrieving revision 1.543
diff -c -p -r1.543 call.c
*** cp/call.c	2 Jul 2005 10:54:32 -0000	1.543
--- cp/call.c	9 Jul 2005 15:24:45 -0000
*************** convert_default_arg (tree type, tree arg
*** 4525,4531 ****
  
    if (TREE_CODE (arg) == CONSTRUCTOR)
      {
!       arg = digest_init (type, arg, 0);
        arg = convert_for_initialization (0, type, arg, LOOKUP_NORMAL,
  					"default argument", fn, parmnum);
      }
--- 4525,4531 ----
  
    if (TREE_CODE (arg) == CONSTRUCTOR)
      {
!       arg = digest_init (type, arg);
        arg = convert_for_initialization (0, type, arg, LOOKUP_NORMAL,
  					"default argument", fn, parmnum);
      }
Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.726
diff -c -p -r1.726 class.c
*** cp/class.c	8 Jul 2005 23:36:55 -0000	1.726
--- cp/class.c	9 Jul 2005 15:24:47 -0000
*************** dump_class_hierarchy (tree t)
*** 6437,6444 ****
  static void
  dump_array (FILE * stream, tree decl)
  {
!   tree inits;
!   int ix;
    HOST_WIDE_INT elt;
    tree size = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (decl)));
  
--- 6437,6444 ----
  static void
  dump_array (FILE * stream, tree decl)
  {
!   tree value;
!   unsigned HOST_WIDE_INT ix;
    HOST_WIDE_INT elt;
    tree size = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (decl)));
  
*************** dump_array (FILE * stream, tree decl)
*** 6450,6459 ****
  			   TFF_PLAIN_IDENTIFIER));
    fprintf (stream, "\n");
  
!   for (ix = 0, inits = CONSTRUCTOR_ELTS (DECL_INITIAL (decl));
!        inits; ix++, inits = TREE_CHAIN (inits))
      fprintf (stream, "%-4ld  %s\n", (long)(ix * elt),
! 	     expr_as_string (TREE_VALUE (inits), TFF_PLAIN_IDENTIFIER));
  }
  
  static void
--- 6450,6459 ----
  			   TFF_PLAIN_IDENTIFIER));
    fprintf (stream, "\n");
  
!   FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (DECL_INITIAL (decl)),
! 			      ix, value)
      fprintf (stream, "%-4ld  %s\n", (long)(ix * elt),
! 	     expr_as_string (value, TFF_PLAIN_IDENTIFIER));
  }
  
  static void
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.1152
diff -c -p -r1.1152 cp-tree.h
*** cp/cp-tree.h	8 Jul 2005 23:36:56 -0000	1.1152
--- cp/cp-tree.h	9 Jul 2005 15:24:49 -0000
*************** extern void decl_shadowed_for_var_insert
*** 2401,2409 ****
  #define BRACE_ENCLOSED_INITIALIZER_P(NODE) \
    (TREE_CODE (NODE) == CONSTRUCTOR && !TREE_TYPE (NODE))
  
! #define EMPTY_CONSTRUCTOR_P(NODE) (TREE_CODE (NODE) == CONSTRUCTOR	   \
! 				   && CONSTRUCTOR_ELTS (NODE) == NULL_TREE \
! 				   && ! TREE_HAS_CONSTRUCTOR (NODE))
  
  /* Nonzero means that an object of this type can not be initialized using
     an initializer list.  */
--- 2401,2410 ----
  #define BRACE_ENCLOSED_INITIALIZER_P(NODE) \
    (TREE_CODE (NODE) == CONSTRUCTOR && !TREE_TYPE (NODE))
  
! #define EMPTY_CONSTRUCTOR_P(NODE) (TREE_CODE (NODE) == CONSTRUCTOR \
! 				   && VEC_empty (constructor_elt, \
! 						 CONSTRUCTOR_ELTS (NODE)) \
! 				   && !TREE_HAS_CONSTRUCTOR (NODE))
  
  /* Nonzero means that an object of this type can not be initialized using
     an initializer list.  */
*************** extern tree finish_increment_expr		(tree
*** 4152,4158 ****
  extern tree finish_this_expr			(void);
  extern tree finish_pseudo_destructor_expr       (tree, tree, tree);
  extern tree finish_unary_op_expr		(enum tree_code, tree);
! extern tree finish_compound_literal		(tree, tree);
  extern tree finish_fname			(tree);
  extern void finish_translation_unit		(void);
  extern tree finish_template_type_parm		(tree, tree);
--- 4153,4159 ----
  extern tree finish_this_expr			(void);
  extern tree finish_pseudo_destructor_expr       (tree, tree, tree);
  extern tree finish_unary_op_expr		(enum tree_code, tree);
! extern tree finish_compound_literal		(tree, VEC(constructor_elt,gc) *);
  extern tree finish_fname			(tree);
  extern void finish_translation_unit		(void);
  extern tree finish_template_type_parm		(tree, tree);
*************** extern void complete_type_check_abstract
*** 4331,4337 ****
  extern int abstract_virtuals_error		(tree, tree);
  
  extern tree store_init_value			(tree, tree);
! extern tree digest_init				(tree, tree, tree *);
  extern tree build_scoped_ref			(tree, tree, tree *);
  extern tree build_x_arrow			(tree);
  extern tree build_m_component_ref		(tree, tree);
--- 4332,4338 ----
  extern int abstract_virtuals_error		(tree, tree);
  
  extern tree store_init_value			(tree, tree);
! extern tree digest_init				(tree, tree);
  extern tree build_scoped_ref			(tree, tree, tree *);
  extern tree build_x_arrow			(tree);
  extern tree build_m_component_ref		(tree, tree);
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1413
diff -c -p -r1.1413 decl.c
*** cp/decl.c	8 Jul 2005 23:36:56 -0000	1.1413
--- cp/decl.c	9 Jul 2005 15:24:52 -0000
*************** static void store_parm_decls (tree);
*** 114,120 ****
  static void initialize_local_var (tree, tree);
  static void expand_static_init (tree, tree);
  static tree next_initializable_field (tree);
! static tree reshape_init (tree, tree *);
  
  /* Erroneous argument lists can use this *IFF* they do not modify it.  */
  tree error_mark_list;
--- 114,120 ----
  static void initialize_local_var (tree, tree);
  static void expand_static_init (tree, tree);
  static tree next_initializable_field (tree);
! static tree reshape_init (tree, tree);
  
  /* Erroneous argument lists can use this *IFF* they do not modify it.  */
  tree error_mark_list;
*************** check_for_uninitialized_const_var (tree 
*** 4103,4108 ****
--- 4103,4120 ----
      error ("uninitialized const %qD", decl);
  }
  
+ 
+ /* Structure holding the current initializer being processed by reshape_init.
+    CUR is a pointer to the current element being processed, END is a pointer
+    after the last element present in the initializer.  */
+ typedef struct reshape_iterator_t
+ {
+   constructor_elt *cur;
+   constructor_elt *end;
+ } reshape_iter;
+ 
+ static tree reshape_init_r (tree, reshape_iter *, bool);
+ 
  /* FIELD is a FIELD_DECL or NULL.  In the former case, the value
     returned is the next FIELD_DECL (possibly FIELD itself) that can be
     initialized.  If there are no more such fields, the return value
*************** next_initializable_field (tree field)
*** 4120,4141 ****
    return field;
  }
  
! /* Subroutine of reshape_init. Reshape the constructor for an array. INITP
!    is the pointer to the old constructor list (to the CONSTRUCTOR_ELTS of
!    the CONSTRUCTOR we are processing), while NEW_INIT is the CONSTRUCTOR we
!    are building.
!    ELT_TYPE is the element type of the array. MAX_INDEX is an INTEGER_CST
!    representing the size of the array minus one (the maximum index), or
!    NULL_TREE if the array was declared without specifying the size.  */
! 
! static bool
! reshape_init_array (tree elt_type, tree max_index,
! 		    tree *initp, tree new_init)
  {
    bool sized_array_p = (max_index != NULL_TREE);
    unsigned HOST_WIDE_INT max_index_cst = 0;
    unsigned HOST_WIDE_INT index;
  
    if (sized_array_p)
      {
        if (host_integerp (max_index, 1))
--- 4132,4154 ----
    return field;
  }
  
! /* Subroutine of reshape_init_array and reshape_init_vector, which does
!    the actual work. ELT_TYPE is the element type of the array. MAX_INDEX is an
!    INTEGER_CST representing the size of the array minus one (the maximum index),
!    or NULL_TREE if the array was declared without specifying the size. D is
!    the iterator within the constructor.  */
! 
! static tree
! reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d)
  {
+   tree new_init;
    bool sized_array_p = (max_index != NULL_TREE);
    unsigned HOST_WIDE_INT max_index_cst = 0;
    unsigned HOST_WIDE_INT index;
  
+   /* The initializer for an array is always a CONSTRUCTOR.  */
+   new_init = build_constructor (NULL_TREE, NULL);
+ 
    if (sized_array_p)
      {
        if (host_integerp (max_index, 1))
*************** reshape_init_array (tree elt_type, tree 
*** 4148,4251 ****
  
    /* Loop until there are no more initializers.  */
    for (index = 0;
!        *initp && (!sized_array_p || index <= max_index_cst);
         ++index)
      {
!       tree element_init;
!       tree designated_index;
  
!       element_init = reshape_init (elt_type, initp);
!       if (element_init == error_mark_node)
! 	return false;
!       TREE_CHAIN (element_init) = CONSTRUCTOR_ELTS (new_init);
!       CONSTRUCTOR_ELTS (new_init) = element_init;
!       designated_index = TREE_PURPOSE (element_init);
!       if (designated_index)
  	{
  	  /* Handle array designated initializers (GNU extension).  */
! 	  if (TREE_CODE (designated_index) == IDENTIFIER_NODE)
  	    {
  	      error ("name %qD used in a GNU-style designated "
! 		     "initializer for an array", designated_index);
! 	      TREE_PURPOSE (element_init) = NULL_TREE;
  	    }
  	  else
  	    gcc_unreachable ();
  	}
      }
  
!   return true;
  }
  
! /* Undo the brace-elision allowed by [dcl.init.aggr] in a
!    brace-enclosed aggregate initializer.
  
!    *INITP is one of a list of initializers describing a brace-enclosed
!    initializer for an entity of the indicated aggregate TYPE.  It may
!    not presently match the shape of the TYPE; for example:
  
!      struct S { int a; int b; };
!      struct S a[] = { 1, 2, 3, 4 };
  
!    Here *INITP will point to TREE_LIST of four elements, rather than a
!    list of two elements, each itself a list of two elements.  This
!    routine transforms INIT from the former form into the latter.  The
!    revised initializer is returned.  */
  
  static tree
! reshape_init (tree type, tree *initp)
  {
!   tree inits;
!   tree old_init;
!   tree old_init_value;
    tree new_init;
-   bool brace_enclosed_p;
-   bool string_init_p;
  
!   old_init = *initp;
!   old_init_value = (TREE_CODE (*initp) == TREE_LIST
! 		    ? TREE_VALUE (*initp) : old_init);
  
!   gcc_assert (old_init_value);
  
!   /* If the initializer is brace-enclosed, pull initializers from the
!      enclosed elements.  Advance past the brace-enclosed initializer
!      now.  */
!   if (TREE_CODE (old_init_value) == CONSTRUCTOR
!       && BRACE_ENCLOSED_INITIALIZER_P (old_init_value))
      {
!       *initp = TREE_CHAIN (old_init);
!       TREE_CHAIN (old_init) = NULL_TREE;
!       inits = CONSTRUCTOR_ELTS (old_init_value);
!       initp = &inits;
!       brace_enclosed_p = true;
      }
!   else
      {
!       inits = NULL_TREE;
!       brace_enclosed_p = false;
      }
  
    /* A non-aggregate type is always initialized with a single
       initializer.  */
    if (!CP_AGGREGATE_TYPE_P (type))
!       {
! 	*initp = TREE_CHAIN (old_init);
! 	TREE_CHAIN (old_init) = NULL_TREE;
! 	/* It is invalid to initialize a non-aggregate type with a
! 	   brace-enclosed initializer.  */
! 	if (brace_enclosed_p)
! 	  {
! 	    error ("brace-enclosed initializer used to initialize %qT",
! 		   type);
! 	    if (TREE_CODE (old_init) == TREE_LIST)
! 	      TREE_VALUE (old_init) = error_mark_node;
! 	    else
! 	      old_init = error_mark_node;
! 	  }
! 
! 	return old_init;
!       }
  
    /* [dcl.init.aggr]
  
--- 4161,4341 ----
  
    /* Loop until there are no more initializers.  */
    for (index = 0;
!        d->cur != d->end && (!sized_array_p || index <= max_index_cst);
         ++index)
      {
!       tree elt_init;
  
!       if (d->cur->index)
  	{
  	  /* Handle array designated initializers (GNU extension).  */
! 	  if (TREE_CODE (d->cur->index) == IDENTIFIER_NODE)
  	    {
  	      error ("name %qD used in a GNU-style designated "
! 		     "initializer for an array", d->cur->index);
  	    }
  	  else
  	    gcc_unreachable ();
  	}
+ 
+       elt_init = reshape_init_r (elt_type, d, /*first_initializer_p=*/false);
+       CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_init), NULL_TREE, elt_init);
      }
  
!   return new_init;
  }
  
! /* Subroutine of reshape_init_r, processes the initializers for arrays.
!    Parameters are the same of reshape_init_r.  */
  
! static tree
! reshape_init_array (tree type, reshape_iter *d)
! {
!   tree max_index = NULL_TREE;
  
!   gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
  
!   if (TYPE_DOMAIN (type))
!     max_index = array_type_nelts (type);
! 
!   return reshape_init_array_1 (TREE_TYPE (type), max_index, d);
! }
! 
! /* Subroutine of reshape_init_r, processes the initializers for vectors.
!    Parameters are the same of reshape_init_r.  */
  
  static tree
! reshape_init_vector (tree type, reshape_iter *d)
  {
!   tree max_index = NULL_TREE;
!   tree rtype;
! 
!   gcc_assert (TREE_CODE (type) == VECTOR_TYPE);
! 
!   if (TREE_CODE (d->cur->value) == CONSTRUCTOR
!       && TREE_HAS_CONSTRUCTOR (d->cur->value))
!     {
!       tree value = d->cur->value;
!       if (!same_type_p (TREE_TYPE (value), type))
! 	{
! 	  error ("invalid type %qT as initializer for a vector of type %qT",
! 		TREE_TYPE (d->cur->value), type);
!   	  value = error_mark_node;
! 	}
!       ++d->cur;
!       return value;
!     }
! 
!   /* For a vector, the representation type is a struct
!       containing a single member which is an array of the
!       appropriate size.  */
!   rtype = TYPE_DEBUG_REPRESENTATION_TYPE (type);
!   if (rtype && TYPE_DOMAIN (TREE_TYPE (TYPE_FIELDS (rtype))))
!     max_index = array_type_nelts (TREE_TYPE (TYPE_FIELDS (rtype)));
! 
!   return reshape_init_array_1 (TREE_TYPE (type), max_index, d);
! }
! 
! /* Subroutine of reshape_init_r, processes the initializers for classes
!    or union. Parameters are the same of reshape_init_r.  */
! 
! static tree
! reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p)
! {
!   tree field;
    tree new_init;
  
!   gcc_assert (CLASS_TYPE_P (type));
  
!   /* The initializer for a class is always a CONSTRUCTOR.  */
!   new_init = build_constructor (NULL_TREE, NULL);
!   field = next_initializable_field (TYPE_FIELDS (type));
  
!   if (!field)
      {
!       /* [dcl.init.aggr]
! 
! 	An initializer for an aggregate member that is an
! 	empty class shall have the form of an empty
! 	initializer-list {}.  */
!       if (!first_initializer_p)
! 	{
! 	  error ("initializer for %qT must be brace-enclosed", type);
! 	  return error_mark_node;
! 	}
!       return new_init;
      }
! 
!   /* Loop through the initializable fields, gathering initializers.  */
!   while (d->cur != d->end)
      {
!       tree field_init;
! 
!       /* Handle designated initializers, as an extension.  */
!       if (d->cur->index)
! 	{
! 	  if (pedantic)
! 	    pedwarn ("ISO C++ does not allow designated initializers");
!   	
! 	  field = lookup_field_1 (type, d->cur->index, /*want_type=*/false);
! 
! 	  if (!field || TREE_CODE (field) != FIELD_DECL)
! 	    error ("%qT has no non-static data member named %qD", type,
! 		  d->cur->index);
! 	}
! 
!       /* If we processed all the member of the class, we are done.  */
!       if (!field)
! 	break;
! 
!       field_init = reshape_init_r (TREE_TYPE (field), d,
! 				   /*first_initializer_p=*/false);
!       CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_init), field, field_init);
! 
!       /* [dcl.init.aggr]
! 
! 	When a union  is  initialized with a brace-enclosed
! 	initializer, the braces shall only contain an
! 	initializer for the first member of the union.  */
!       if (TREE_CODE (type) == UNION_TYPE)
! 	break;
! 
!       field = next_initializable_field (TREE_CHAIN (field));
      }
  
+   return new_init;
+ }
+ 
+ /* Subroutine of reshape_init, which processes a single initializer (part of
+    a CONSTRUCTOR). TYPE is the type of the variable being initialized, D is the
+    iterator within the CONSTRUCTOR which points to the initializer to process.
+    FIRST_INITIALIZER_P is true if this is the first initializer of the
+    CONSTRUCTOR node.  */
+ 
+ static tree
+ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p)
+ {
+   tree init = d->cur->value;
+ 
    /* A non-aggregate type is always initialized with a single
       initializer.  */
    if (!CP_AGGREGATE_TYPE_P (type))
!     {
!       /* It is invalid to initialize a non-aggregate type with a
! 	 brace-enclosed initializer.
! 	 We need to check for BRACE_ENCLOSED_INITIALIZER_P here because
! 	 of g++.old-deja/g++.mike/p7626.C: a pointer-to-member constant is
! 	 a CONSTRUCTOR (with a record type).  */
!       if (TREE_CODE (init) == CONSTRUCTOR
! 	  && BRACE_ENCLOSED_INITIALIZER_P (init))  /* p7626.C */
! 	{
! 	  error ("braces around scalar initializer for type %qT", type);
! 	  init = error_mark_node;
! 	}
! 	
!       d->cur++;
!       return init;
!     }
  
    /* [dcl.init.aggr]
  
*************** reshape_init (tree type, tree *initp)
*** 4256,4394 ****
       non-empty subaggregate, brace elision is assumed and the
       initializer is considered for the initialization of the first
       member of the subaggregate.  */
!   if (!brace_enclosed_p
!       && can_convert_arg (type, TREE_TYPE (old_init_value), old_init_value))
      {
!       *initp = TREE_CHAIN (old_init);
!       TREE_CHAIN (old_init) = NULL_TREE;
!       return old_init;
      }
  
!   string_init_p = false;
!   if (TREE_CODE (old_init_value) == STRING_CST
!       && TREE_CODE (type) == ARRAY_TYPE
        && char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type))))
      {
!       /* [dcl.init.string]
  
! 	 A char array (whether plain char, signed char, or unsigned char)
! 	 can be initialized by a string-literal (optionally enclosed in
! 	 braces); a wchar_t array can be initialized by a wide
! 	 string-literal (optionally enclosed in braces).  */
!       new_init = old_init;
!       /* Move past the initializer.  */
!       *initp = TREE_CHAIN (old_init);
!       TREE_CHAIN (old_init) = NULL_TREE;
!       string_init_p = true;
      }
    else
!     {
!       /* Build a CONSTRUCTOR to hold the contents of the aggregate.  */
!       new_init = build_constructor (NULL_TREE, NULL_TREE);
  
!       if (CLASS_TYPE_P (type))
! 	{
! 	  tree field;
  
! 	  field = next_initializable_field (TYPE_FIELDS (type));
  
! 	  if (!field)
! 	    {
! 	      /* [dcl.init.aggr]
  
! 		 An initializer for an aggregate member that is an
! 		 empty class shall have the form of an empty
! 		 initializer-list {}.  */
! 	      if (!brace_enclosed_p)
! 		{
! 		  error ("initializer for %qT must be brace-enclosed", type);
! 		  return error_mark_node;
! 		}
! 	    }
! 	  else
! 	    {
! 	      /* Loop through the initializable fields, gathering
! 		 initializers.  */
! 	      while (*initp)
! 		{
! 		  tree field_init;
  
! 		  /* Handle designated initializers, as an extension.  */
! 		  if (TREE_PURPOSE (*initp))
! 		    {
! 		      if (pedantic)
! 			pedwarn ("ISO C++ does not allow designated initializers");
! 		      field = lookup_field_1 (type, TREE_PURPOSE (*initp),
! 					      /*want_type=*/false);
! 		      if (!field || TREE_CODE (field) != FIELD_DECL)
! 			error ("%qT has no non-static data member named %qD",
! 			       type, TREE_PURPOSE (*initp));
! 		    }
! 		  if (!field)
! 		    break;
  
! 		  field_init = reshape_init (TREE_TYPE (field), initp);
! 		  if (field_init == error_mark_node)
! 		    return error_mark_node;
! 		  TREE_CHAIN (field_init) = CONSTRUCTOR_ELTS (new_init);
! 		  CONSTRUCTOR_ELTS (new_init) = field_init;
! 		  /* [dcl.init.aggr]
! 
! 		     When a union  is  initialized with a brace-enclosed
! 		     initializer, the braces shall only contain an
! 		     initializer for the first member of the union.  */
! 		  if (TREE_CODE (type) == UNION_TYPE)
! 		    break;
! 		  field = next_initializable_field (TREE_CHAIN (field));
! 		}
! 	    }
! 	}
!       else if (TREE_CODE (type) == ARRAY_TYPE
! 	       || TREE_CODE (type) == VECTOR_TYPE)
! 	{
! 	    /* If the bound of the array is known, take no more initializers
! 	      than are allowed.  */
! 	    tree max_index = NULL_TREE;
! 	    if (TREE_CODE (type) == ARRAY_TYPE)
! 	      {
! 		if (TYPE_DOMAIN (type))
! 		  max_index = array_type_nelts (type);
! 	      }
! 	    else
! 	      {
! 		/* For a vector, the representation type is a struct
! 		  containing a single member which is an array of the
! 		  appropriate size.  */
! 		tree rtype = TYPE_DEBUG_REPRESENTATION_TYPE (type);
! 		if (rtype && TYPE_DOMAIN (TREE_TYPE (TYPE_FIELDS (rtype))))
! 		  max_index = array_type_nelts (TREE_TYPE (TYPE_FIELDS
! 							   (rtype)));
! 	      }
  
! 	  if (!reshape_init_array (TREE_TYPE (type), max_index,
! 				   initp, new_init))
! 	    return error_mark_node;
! 	}
!       else
! 	gcc_unreachable ();
  
!       /* The initializers were placed in reverse order in the
! 	 CONSTRUCTOR.  */
!       CONSTRUCTOR_ELTS (new_init) = nreverse (CONSTRUCTOR_ELTS (new_init));
! 
!       if (TREE_CODE (old_init) == TREE_LIST)
! 	new_init = build_tree_list (TREE_PURPOSE (old_init), new_init);
!     }
! 
!   /* If there are more initializers than necessary, issue a
!      diagnostic.  */
!   if (*initp)
!     {
!       if (brace_enclosed_p)
! 	error ("too many initializers for %qT", type);
!       else if (warn_missing_braces && !string_init_p)
! 	warning (0, "missing braces around initializer");
!     }
  
    return new_init;
  }
--- 4346,4469 ----
       non-empty subaggregate, brace elision is assumed and the
       initializer is considered for the initialization of the first
       member of the subaggregate.  */
!   if (TREE_CODE (init) != CONSTRUCTOR
!       && can_convert_arg (type, TREE_TYPE (init), init))
      {
!       d->cur++;
!       return init;
      }
  
!   /* [dcl.init.string]
! 
!       A char array (whether plain char, signed char, or unsigned char)
!       can be initialized by a string-literal (optionally enclosed in
!       braces); a wchar_t array can be initialized by a wide
!       string-literal (optionally enclosed in braces).  */
!   if (TREE_CODE (type) == ARRAY_TYPE
        && char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type))))
      {
!       tree str_init = init;
! 
!       /* Strip one level of braces if and only if they enclose a single
!          element (as allowed by [dcl.init.string]).  */
!       if (!first_initializer_p
! 	  && TREE_CODE (str_init) == CONSTRUCTOR
! 	  && VEC_length (constructor_elt, CONSTRUCTOR_ELTS (str_init)) == 1)
! 	{
! 	  str_init = VEC_index (constructor_elt,
! 				CONSTRUCTOR_ELTS (str_init), 0)->value;
! 	}
!   
!       /* If it's a string literal, then it's the initializer for the array
!          as a whole. Otherwise, continue with normal initialization for
! 	 array types (one value per array element).  */
!       if (TREE_CODE (str_init) == STRING_CST)
! 	{
! 	  d->cur++;
! 	  return str_init;
! 	}
!     }
! 
!   /* The following cases are about aggregates. If we are not within a full
!      initializer already, and there is not a CONSTRUCTOR, it means that there
!      is a missing set of braces (that is, we are processing the case for
!      which reshape_init exists).  */
!   if (!first_initializer_p)
!     {
!       if (TREE_CODE (init) == CONSTRUCTOR)
! 	{
! 	  /* For a nested compound literal, there is no need to reshape since
! 	     brace elision is not allowed. Even if we decided to allow it,
! 	     we should add a call to reshape_init in finish_compound_literal,
! 	     before calling digest_init, so changing this code would still
! 	     not be necessary.  */
! 	  if (!TREE_HAS_CONSTRUCTOR (init))
! 	    {
! 	      ++d->cur;
! 	      gcc_assert (BRACE_ENCLOSED_INITIALIZER_P (init));
! 	      return reshape_init (type, init);
! 	    }
! 	  else
! 	    gcc_assert (!BRACE_ENCLOSED_INITIALIZER_P (init));
! 	}
  
!       warning (OPT_Wmissing_braces, "missing braces around initializer for %qT",
! 	       type);
      }
+ 
+   /* Dispatch to specialized routines.  */
+   if (CLASS_TYPE_P (type))
+     return reshape_init_class (type, d, first_initializer_p);
+   else if (TREE_CODE (type) == ARRAY_TYPE)
+     return reshape_init_array (type, d);
+   else if (TREE_CODE (type) == VECTOR_TYPE)
+     return reshape_init_vector (type, d);
    else
!     gcc_unreachable();
! }
  
! /* Undo the brace-elision allowed by [dcl.init.aggr] in a
!    brace-enclosed aggregate initializer.
  
!    INIT is the CONSTRUCTOR containing the list of initializers describing
!    a brace-enclosed initializer for an entity of the indicated aggregate TYPE.
!    It may not presently match the shape of the TYPE; for example:
  
!      struct S { int a; int b; };
!      struct S a[] = { 1, 2, 3, 4 };
  
!    Here INIT will hold a VEC of four elements, rather than a
!    VEC of two elements, each itself a VEC of two elements.  This
!    routine transforms INIT from the former form into the latter.  The
!    revised CONSTRUCTOR node is returned.  */
  
! static tree
! reshape_init (tree type, tree init)
! {
!   VEC(constructor_elt, gc) *v;
!   reshape_iter d;
!   tree new_init;
  
!   gcc_assert (TREE_CODE (init) == CONSTRUCTOR);
!   gcc_assert (BRACE_ENCLOSED_INITIALIZER_P (init));
  
!   v = CONSTRUCTOR_ELTS (init);
  
!   /* An empty constructor does not need reshaping, and it is always a valid
!      initializer.  */
!   if (VEC_empty (constructor_elt, v))
!     return init;
! 
!   /* Recurse on this CONSTRUCTOR.  */
!   d.cur = VEC_index (constructor_elt, v, 0);
!   d.end = d.cur + VEC_length (constructor_elt, v);
! 
!   new_init = reshape_init_r (type, &d, true);
! 
!   /* Make sure all the element of the constructor were used. Otherwise,
!      issue an error about exceeding initializers.  */
!   if (d.cur != d.end)
!     error ("too many initializers for %qT", type);
  
    return new_init;
  }
*************** check_initializer (tree decl, tree init,
*** 4455,4474 ****
      init = grok_reference_init (decl, type, init, cleanup);
    else if (init)
      {
        if (TREE_CODE (init) == CONSTRUCTOR
! 	  && BRACE_ENCLOSED_INITIALIZER_P (init))
  	{
! 	  /* [dcl.init] paragraph 13,
! 	     If T is a scalar type, then a declaration of the form
! 	     T x = { a };
! 	     is equivalent to
! 	     T x = a;
! 
! 	     reshape_init will complain about the extra braces,
! 	     and doesn't do anything useful in the case where TYPE is
! 	     scalar, so just don't call it.  */
! 	  if (CP_AGGREGATE_TYPE_P (type))
! 	    init = reshape_init (type, &init);
  
  	  if ((*targetm.vector_opaque_p) (type))
  	    {
--- 4530,4542 ----
      init = grok_reference_init (decl, type, init, cleanup);
    else if (init)
      {
+       /* Do not reshape constructors of vectors (they don't need to be
+          reshaped.  */
        if (TREE_CODE (init) == CONSTRUCTOR
! 	  && !TREE_HAS_CONSTRUCTOR (init)
! 	  && !TREE_TYPE (init))  /* ptrmemfunc */
  	{
! 	  init = reshape_init (type, init);
  
  	  if ((*targetm.vector_opaque_p) (type))
  	    {
*************** check_initializer (tree decl, tree init,
*** 4486,4494 ****
  	{
  	  if (TREE_CODE (type) == ARRAY_TYPE)
  	    goto initialize_aggr;
! 	  else if (TREE_CODE (init) == CONSTRUCTOR
! 		   && BRACE_ENCLOSED_INITIALIZER_P (init))
  	    {
  	      if (TYPE_NON_AGGREGATE_CLASS (type))
  		{
  		  error ("%qD must be initialized by constructor, "
--- 4554,4562 ----
  	{
  	  if (TREE_CODE (type) == ARRAY_TYPE)
  	    goto initialize_aggr;
! 	  else if (TREE_CODE (init) == CONSTRUCTOR)
  	    {
+ 	      gcc_assert (BRACE_ENCLOSED_INITIALIZER_P (init));
  	      if (TYPE_NON_AGGREGATE_CLASS (type))
  		{
  		  error ("%qD must be initialized by constructor, "
*************** initialize_local_var (tree decl, tree in
*** 4713,4719 ****
  void
  initialize_artificial_var (tree decl, tree init)
  {
!   DECL_INITIAL (decl) = build_constructor (NULL_TREE, init);
    DECL_INITIALIZED_P (decl) = 1;
    determine_visibility (decl);
    layout_var_decl (decl);
--- 4781,4787 ----
  void
  initialize_artificial_var (tree decl, tree init)
  {
!   DECL_INITIAL (decl) = build_constructor_from_list (NULL_TREE, init);
    DECL_INITIALIZED_P (decl) = 1;
    determine_visibility (decl);
    layout_var_decl (decl);
*************** cp_complete_array_type (tree *ptype, tre
*** 5401,5414 ****
    if (initial_value)
      {
        /* An array of character type can be initialized from a
! 	 brace-enclosed string constant.  */
        if (char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (*ptype)))
  	  && TREE_CODE (initial_value) == CONSTRUCTOR
! 	  && CONSTRUCTOR_ELTS (initial_value)
! 	  && (TREE_CODE (TREE_VALUE (CONSTRUCTOR_ELTS (initial_value)))
! 	      == STRING_CST)
! 	  && TREE_CHAIN (CONSTRUCTOR_ELTS (initial_value)) == NULL_TREE)
! 	initial_value = TREE_VALUE (CONSTRUCTOR_ELTS (initial_value));
      }
  
    failure = complete_array_type (ptype, initial_value, do_default);
--- 5469,5489 ----
    if (initial_value)
      {
        /* An array of character type can be initialized from a
! 	 brace-enclosed string constant.
! 
! 	 FIXME: this code is duplicated from reshape_init. Probably
! 	 we should just call reshape_init here?  */
        if (char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (*ptype)))
  	  && TREE_CODE (initial_value) == CONSTRUCTOR
! 	  && !VEC_empty (constructor_elt, CONSTRUCTOR_ELTS (initial_value)))
! 	{
! 	  VEC(constructor_elt,gc) *v = CONSTRUCTOR_ELTS (initial_value);
! 	  tree value = VEC_index (constructor_elt, v, 0)->value;
! 
! 	  if (TREE_CODE (value) == STRING_CST
! 	      && VEC_length (constructor_elt, v) == 1)
! 	    initial_value = value;
! 	}
      }
  
    failure = complete_array_type (ptype, initial_value, do_default);
Index: cp/decl2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl2.c,v
retrieving revision 1.791
diff -c -p -r1.791 decl2.c
*** cp/decl2.c	8 Jul 2005 23:37:00 -0000	1.791
--- cp/decl2.c	9 Jul 2005 15:24:53 -0000
*************** grokfield (const cp_declarator *declarat
*** 903,939 ****
        else if (pedantic && TREE_CODE (value) != VAR_DECL)
  	/* Already complained in grokdeclarator.  */
  	init = NULL_TREE;
!       else
  	{
! 	  /* We allow initializers to become parameters to base
! 	     initializers.  */
! 	  if (TREE_CODE (init) == TREE_LIST)
! 	    {
! 	      if (TREE_CHAIN (init) == NULL_TREE)
! 		init = TREE_VALUE (init);
! 	      else
! 		init = digest_init (TREE_TYPE (value), init, (tree *)0);
! 	    }
  
! 	  if (!processing_template_decl)
  	    {
! 	      if (TREE_CODE (init) == CONSTRUCTOR)
! 		init = digest_init (TREE_TYPE (value), init, (tree *)0);
! 	      else
! 		init = integral_constant_value (init);
! 
! 	      if (init != error_mark_node && ! TREE_CONSTANT (init))
  		{
! 		  /* We can allow references to things that are effectively
! 		     static, since references are initialized with the
! 		     address.  */
! 		  if (TREE_CODE (TREE_TYPE (value)) != REFERENCE_TYPE
! 		      || (TREE_STATIC (init) == 0
! 			  && (!DECL_P (init) || DECL_EXTERNAL (init) == 0)))
! 		    {
! 		      error ("field initializer is not constant");
! 		      init = error_mark_node;
! 		    }
  		}
  	    }
  	}
--- 903,926 ----
        else if (pedantic && TREE_CODE (value) != VAR_DECL)
  	/* Already complained in grokdeclarator.  */
  	init = NULL_TREE;
!       else if (!processing_template_decl)
  	{
! 	  if (TREE_CODE (init) == CONSTRUCTOR)
! 	    init = digest_init (TREE_TYPE (value), init);
! 	  else
! 	    init = integral_constant_value (init);
  
! 	  if (init != error_mark_node && !TREE_CONSTANT (init))
  	    {
! 	      /* We can allow references to things that are effectively
! 		 static, since references are initialized with the
! 		 address.  */
! 	      if (TREE_CODE (TREE_TYPE (value)) != REFERENCE_TYPE
! 		  || (TREE_STATIC (init) == 0
! 		      && (!DECL_P (init) || DECL_EXTERNAL (init) == 0)))
  		{
! 		  error ("field initializer is not constant");
! 		  init = error_mark_node;
  		}
  	    }
  	}
*************** coerce_delete_type (tree type)
*** 1262,1272 ****
  static void
  mark_vtable_entries (tree decl)
  {
!   tree entries = CONSTRUCTOR_ELTS (DECL_INITIAL (decl));
  
!   for (; entries; entries = TREE_CHAIN (entries))
      {
-       tree fnaddr = TREE_VALUE (entries);
        tree fn;
  
        STRIP_NOPS (fnaddr);
--- 1249,1260 ----
  static void
  mark_vtable_entries (tree decl)
  {
!   tree fnaddr;
!   unsigned HOST_WIDE_INT idx;
  
!   FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (DECL_INITIAL (decl)),
! 			      idx, fnaddr)
      {
        tree fn;
  
        STRIP_NOPS (fnaddr);
Index: cp/error.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/error.c,v
retrieving revision 1.289
diff -c -p -r1.289 error.c
*** cp/error.c	2 Jul 2005 10:54:48 -0000	1.289
--- cp/error.c	9 Jul 2005 15:24:54 -0000
*************** dump_expr_list (tree l, int flags)
*** 1266,1271 ****
--- 1300,1322 ----
      }
  }
  
+ /* Print out a vector of initializers (subr of dump_expr).  */
+ 
+ static void
+ dump_expr_init_vec (VEC(constructor_elt,gc) *v, int flags)
+ {
+   unsigned HOST_WIDE_INT idx;
+   tree value;
+ 
+   FOR_EACH_CONSTRUCTOR_VALUE (v, idx, value)
+     {
+       dump_expr (value, flags | TFF_EXPR_IN_PARENS);
+       if (idx != VEC_length (constructor_elt, v) - 1)
+ 	pp_separate_with_comma (cxx_pp);
+     }
+ }
+ 
+ 
  /* Print out an expression E under control of FLAGS.  */
  
  static void
*************** dump_expr (tree t, int flags)
*** 1659,1665 ****
  		}
  	    }
  	}
!       if (TREE_TYPE (t) && !CONSTRUCTOR_ELTS (t))
  	{
  	  dump_type (TREE_TYPE (t), 0);
  	  pp_cxx_left_paren (cxx_pp);
--- 1710,1716 ----
  		}
  	    }
  	}
!       if (TREE_TYPE (t) && EMPTY_CONSTRUCTOR_P (t))
  	{
  	  dump_type (TREE_TYPE (t), 0);
  	  pp_cxx_left_paren (cxx_pp);
*************** dump_expr (tree t, int flags)
*** 1668,1674 ****
        else
  	{
  	  pp_cxx_left_brace (cxx_pp);
! 	  dump_expr_list (CONSTRUCTOR_ELTS (t), flags);
  	  pp_cxx_right_brace (cxx_pp);
  	}
  
--- 1719,1725 ----
        else
  	{
  	  pp_cxx_left_brace (cxx_pp);
! 	  dump_expr_init_vec (CONSTRUCTOR_ELTS (t), flags);
  	  pp_cxx_right_brace (cxx_pp);
  	}
  
Index: cp/init.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/init.c,v
retrieving revision 1.424
diff -c -p -r1.424 init.c
*** cp/init.c	2 Jul 2005 10:54:49 -0000	1.424
--- cp/init.c	9 Jul 2005 15:24:55 -0000
*************** build_zero_init (tree type, tree nelts, 
*** 184,195 ****
    else if (CLASS_TYPE_P (type))
      {
        tree field;
!       tree inits;
  
-       /* Build a constructor to contain the initializations.  */
-       init = build_constructor (type, NULL_TREE);
        /* Iterate over the fields, building initializations.  */
-       inits = NULL_TREE;
        for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
  	{
  	  if (TREE_CODE (field) != FIELD_DECL)
--- 184,192 ----
    else if (CLASS_TYPE_P (type))
      {
        tree field;
!       VEC(constructor_elt,gc) *v = NULL;
  
        /* Iterate over the fields, building initializations.  */
        for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
  	{
  	  if (TREE_CODE (field) != FIELD_DECL)
*************** build_zero_init (tree type, tree nelts, 
*** 200,226 ****
  	     over TYPE_FIELDs will result in correct initialization of
  	     all of the subobjects.  */
  	  if (static_storage_p && !zero_init_p (TREE_TYPE (field)))
! 	    inits = tree_cons (field,
! 			       build_zero_init (TREE_TYPE (field),
! 						/*nelts=*/NULL_TREE,
! 						static_storage_p),
! 			       inits);
  
  	  /* For unions, only the first field is initialized.  */
  	  if (TREE_CODE (type) == UNION_TYPE)
  	    break;
  	}
!       CONSTRUCTOR_ELTS (init) = nreverse (inits);
      }
    else if (TREE_CODE (type) == ARRAY_TYPE)
      {
        tree max_index;
!       tree inits;
  
-       /* Build a constructor to contain the initializations.  */
-       init = build_constructor (type, NULL_TREE);
        /* Iterate over the array elements, building initializations.  */
-       inits = NULL_TREE;
        if (nelts)
  	max_index = fold_build2 (MINUS_EXPR, TREE_TYPE (nelts),
  				 nelts, integer_one_node);
--- 197,223 ----
  	     over TYPE_FIELDs will result in correct initialization of
  	     all of the subobjects.  */
  	  if (static_storage_p && !zero_init_p (TREE_TYPE (field)))
! 	    {
! 	      tree value = build_zero_init (TREE_TYPE (field),
! 					    /*nelts=*/NULL_TREE,
! 					    static_storage_p);
! 	      CONSTRUCTOR_APPEND_ELT(v, field, value);
! 	    }
  
  	  /* For unions, only the first field is initialized.  */
  	  if (TREE_CODE (type) == UNION_TYPE)
  	    break;
  	}
! 
! 	/* Build a constructor to contain the initializations.  */
! 	init = build_constructor (type, v);
      }
    else if (TREE_CODE (type) == ARRAY_TYPE)
      {
        tree max_index;
!       VEC(constructor_elt,gc) *v = NULL;
  
        /* Iterate over the array elements, building initializations.  */
        if (nelts)
  	max_index = fold_build2 (MINUS_EXPR, TREE_TYPE (nelts),
  				 nelts, integer_one_node);
*************** build_zero_init (tree type, tree nelts, 
*** 232,252 ****
  	 have an upper bound of -1.  */
        if (!tree_int_cst_equal (max_index, integer_minus_one_node))
  	{
! 	  tree elt_init = build_zero_init (TREE_TYPE (type),
! 					   /*nelts=*/NULL_TREE,
! 					   static_storage_p);
! 	  tree range;
  
  	  /* If this is a one element array, we just use a regular init.  */
  	  if (tree_int_cst_equal (size_zero_node, max_index))
! 	    range = size_zero_node;
  	  else
! 	   range = build2 (RANGE_EXPR, sizetype, size_zero_node, max_index);
  
! 	  inits = tree_cons (range, elt_init, inits);
  	}
  
!       CONSTRUCTOR_ELTS (init) = nreverse (inits);
      }
    else
      gcc_assert (TREE_CODE (type) == REFERENCE_TYPE);
--- 229,253 ----
  	 have an upper bound of -1.  */
        if (!tree_int_cst_equal (max_index, integer_minus_one_node))
  	{
! 	  constructor_elt *ce;
! 
! 	  v = VEC_alloc (constructor_elt, gc, 1);
! 	  ce = VEC_quick_push (constructor_elt, v, NULL);
  
  	  /* If this is a one element array, we just use a regular init.  */
  	  if (tree_int_cst_equal (size_zero_node, max_index))
! 	    ce->index = size_zero_node;
  	  else
! 	    ce->index = build2 (RANGE_EXPR, sizetype, size_zero_node,
! 				max_index);
  
! 	  ce->value = build_zero_init (TREE_TYPE (type),
! 				       /*nelts=*/NULL_TREE,
! 				       static_storage_p);
  	}
  
!       /* Build a constructor to contain the initializations.  */
!       init = build_constructor (type, v);
      }
    else
      gcc_assert (TREE_CODE (type) == REFERENCE_TYPE);
*************** expand_default_init (tree binfo, tree tr
*** 1191,1197 ****
  	{
  	  /* A brace-enclosed initializer for an aggregate.  */
  	  gcc_assert (CP_AGGREGATE_TYPE_P (type));
! 	  init = digest_init (type, init, (tree *)NULL);
  	}
        else
  	init = ocp_convert (type, init, CONV_IMPLICIT|CONV_FORCE_TEMP, flags);
--- 1192,1198 ----
  	{
  	  /* A brace-enclosed initializer for an aggregate.  */
  	  gcc_assert (CP_AGGREGATE_TYPE_P (type));
! 	  init = digest_init (type, init);
  	}
        else
  	init = ocp_convert (type, init, CONV_IMPLICIT|CONV_FORCE_TEMP, flags);
*************** build_vec_init (tree base, tree maxindex
*** 2417,2423 ****
        && ((TREE_CODE (init) == CONSTRUCTOR
  	   /* Don't do this if the CONSTRUCTOR might contain something
  	      that might throw and require us to clean up.  */
! 	   && (CONSTRUCTOR_ELTS (init) == NULL_TREE
  	       || ! TYPE_HAS_NONTRIVIAL_DESTRUCTOR (inner_elt_type)))
  	  || from_array))
      {
--- 2418,2424 ----
        && ((TREE_CODE (init) == CONSTRUCTOR
  	   /* Don't do this if the CONSTRUCTOR might contain something
  	      that might throw and require us to clean up.  */
! 	   && (VEC_empty (constructor_elt, CONSTRUCTOR_ELTS (init))
  	       || ! TYPE_HAS_NONTRIVIAL_DESTRUCTOR (inner_elt_type)))
  	  || from_array))
      {
*************** build_vec_init (tree base, tree maxindex
*** 2485,2497 ****
      {
        /* Do non-default initialization of non-POD arrays resulting from
  	 brace-enclosed initializers.  */
! 
!       tree elts;
        from_array = 0;
  
!       for (elts = CONSTRUCTOR_ELTS (init); elts; elts = TREE_CHAIN (elts))
  	{
- 	  tree elt = TREE_VALUE (elts);
  	  tree baseref = build1 (INDIRECT_REF, type, base);
  
  	  num_initialized_elts++;
--- 2486,2497 ----
      {
        /* Do non-default initialization of non-POD arrays resulting from
  	 brace-enclosed initializers.  */
!       unsigned HOST_WIDE_INT idx;
!       tree elt;
        from_array = 0;
  
!       FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (init), idx, elt)
  	{
  	  tree baseref = build1 (INDIRECT_REF, type, base);
  
  	  num_initialized_elts++;
Index: cp/parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.346
diff -c -p -r1.346 parser.c
*** cp/parser.c	2 Jul 2005 13:19:38 -0000	1.346
--- cp/parser.c	9 Jul 2005 15:25:00 -0000
*************** static tree cp_parser_initializer
*** 1546,1552 ****
    (cp_parser *, bool *, bool *);
  static tree cp_parser_initializer_clause
    (cp_parser *, bool *);
! static tree cp_parser_initializer_list
    (cp_parser *, bool *);
  
  static bool cp_parser_ctor_initializer_opt_and_function_body
--- 1546,1552 ----
    (cp_parser *, bool *, bool *);
  static tree cp_parser_initializer_clause
    (cp_parser *, bool *);
! static VEC(constructor_elt,gc) *cp_parser_initializer_list
    (cp_parser *, bool *);
  
  static bool cp_parser_ctor_initializer_opt_and_function_body
*************** cp_parser_postfix_expression (cp_parser 
*** 4027,4033 ****
  	if (cp_parser_allow_gnu_extensions_p (parser)
  	    && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
  	  {
! 	    tree initializer_list = NULL_TREE;
  	    bool saved_in_type_id_in_expr_p;
  
  	    cp_parser_parse_tentatively (parser);
--- 4027,4033 ----
  	if (cp_parser_allow_gnu_extensions_p (parser)
  	    && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
  	  {
! 	    VEC(constructor_elt,gc) *initializer_list = NULL;
  	    bool saved_in_type_id_in_expr_p;
  
  	    cp_parser_parse_tentatively (parser);
*************** cp_parser_initializer (cp_parser* parser
*** 12298,12304 ****
     returned is simply a representation for the expression.
  
     Otherwise, a CONSTRUCTOR is returned.  The CONSTRUCTOR_ELTS will be
!    the elements of the initializer-list (or NULL_TREE, if the last
     production is used).  The TREE_TYPE for the CONSTRUCTOR will be
     NULL_TREE.  There is no way to detect whether or not the optional
     trailing `,' was provided.  NON_CONSTANT_P is as for
--- 12298,12304 ----
     returned is simply a representation for the expression.
  
     Otherwise, a CONSTRUCTOR is returned.  The CONSTRUCTOR_ELTS will be
!    the elements of the initializer-list (or NULL, if the last
     production is used).  The TREE_TYPE for the CONSTRUCTOR will be
     NULL_TREE.  There is no way to detect whether or not the optional
     trailing `,' was provided.  NON_CONSTANT_P is as for
*************** cp_parser_initializer_clause (cp_parser*
*** 12358,12372 ****
       identifier : initializer-clause
       initializer-list, identifier : initializer-clause
  
!    Returns a TREE_LIST.  The TREE_VALUE of each node is an expression
!    for the initializer.  If the TREE_PURPOSE is non-NULL, it is the
     IDENTIFIER_NODE naming the field to initialize.  NON_CONSTANT_P is
     as for cp_parser_initializer.  */
  
! static tree
  cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p)
  {
!   tree initializers = NULL_TREE;
  
    /* Assume all of the expressions are constant.  */
    *non_constant_p = false;
--- 12358,12372 ----
       identifier : initializer-clause
       initializer-list, identifier : initializer-clause
  
!    Returns a VEC of constructor_elt.  The VALUE of each elt is an expression
!    for the initializer.  If the INDEX of the elt is non-NULL, it is the
     IDENTIFIER_NODE naming the field to initialize.  NON_CONSTANT_P is
     as for cp_parser_initializer.  */
  
! static VEC(constructor_elt,gc) *
  cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p)
  {
!   VEC(constructor_elt,gc) *v = NULL;
  
    /* Assume all of the expressions are constant.  */
    *non_constant_p = false;
*************** cp_parser_initializer_list (cp_parser* p
*** 12400,12407 ****
        /* If any clause is non-constant, so is the entire initializer.  */
        if (clause_non_constant_p)
  	*non_constant_p = true;
!       /* Add it to the list.  */
!       initializers = tree_cons (identifier, initializer, initializers);
  
        /* If the next token is not a comma, we have reached the end of
  	 the list.  */
--- 12400,12408 ----
        /* If any clause is non-constant, so is the entire initializer.  */
        if (clause_non_constant_p)
  	*non_constant_p = true;
! 
!       /* Add it to the vector.  */
!       CONSTRUCTOR_APPEND_ELT(v, identifier, initializer);
  
        /* If the next token is not a comma, we have reached the end of
  	 the list.  */
*************** cp_parser_initializer_list (cp_parser* p
*** 12420,12428 ****
        cp_lexer_consume_token (parser->lexer);
      }
  
!   /* The initializers were built up in reverse order, so we need to
!      reverse them now.  */
!   return nreverse (initializers);
  }
  
  /* Classes [gram.class] */
--- 12421,12427 ----
        cp_lexer_consume_token (parser->lexer);
      }
  
!   return v;
  }
  
  /* Classes [gram.class] */
Index: cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.1014
diff -c -p -r1.1014 pt.c
*** cp/pt.c	8 Jul 2005 23:37:01 -0000	1.1014
--- cp/pt.c	9 Jul 2005 15:25:04 -0000
*************** tsubst_copy (tree t, tree args, tsubst_f
*** 8003,8015 ****
  	return t;
  
      case CONSTRUCTOR:
!       {
! 	r = build_constructor
! 	  (tsubst (TREE_TYPE (t), args, complain, in_decl),
! 	   tsubst_copy (CONSTRUCTOR_ELTS (t), args, complain, in_decl));
! 	TREE_HAS_CONSTRUCTOR (r) = TREE_HAS_CONSTRUCTOR (t);
! 	return r;
!       }
  
      case VA_ARG_EXPR:
        return build_x_va_arg (tsubst_copy (TREE_OPERAND (t, 0), args, complain,
--- 8003,8010 ----
  	return t;
  
      case CONSTRUCTOR:
!       /* This is handled by tsubst_copy_and_build.  */
!       gcc_unreachable ();
  
      case VA_ARG_EXPR:
        return build_x_va_arg (tsubst_copy (TREE_OPERAND (t, 0), args, complain,
*************** tsubst_copy_and_build (tree t,
*** 8811,8848 ****
  
      case CONSTRUCTOR:
        {
  	tree r;
- 	tree elts;
  	tree type = tsubst (TREE_TYPE (t), args, complain, in_decl);
! 	bool purpose_p;
  
  	/* digest_init will do the wrong thing if we let it.  */
  	if (type && TYPE_PTRMEMFUNC_P (type))
  	  return t;
  
! 	r = NULL_TREE;
! 	/* We do not want to process the purpose of aggregate
  	   initializers as they are identifier nodes which will be
  	   looked up by digest_init.  */
! 	purpose_p = !(type && IS_AGGR_TYPE (type));
! 	for (elts = CONSTRUCTOR_ELTS (t);
! 	     elts;
! 	     elts = TREE_CHAIN (elts))
! 	  {
! 	    tree purpose = TREE_PURPOSE (elts);
! 	    tree value = TREE_VALUE (elts);
  
! 	    if (purpose && purpose_p)
! 	      purpose = RECUR (purpose);
! 	    value = RECUR (value);
! 	    r = tree_cons (purpose, value, r);
  	  }
  
! 	r = build_constructor (NULL_TREE, nreverse (r));
  	TREE_HAS_CONSTRUCTOR (r) = TREE_HAS_CONSTRUCTOR (t);
  
  	if (type)
! 	  return digest_init (type, r, 0);
  	return r;
        }
  
--- 8806,8840 ----
  
      case CONSTRUCTOR:
        {
+ 	VEC(constructor_elt,gc) *n;
+ 	constructor_elt *ce;
+ 	unsigned HOST_WIDE_INT idx;
  	tree r;
  	tree type = tsubst (TREE_TYPE (t), args, complain, in_decl);
! 	bool process_index_p;
  
  	/* digest_init will do the wrong thing if we let it.  */
  	if (type && TYPE_PTRMEMFUNC_P (type))
  	  return t;
  
! 	/* We do not want to process the index of aggregate
  	   initializers as they are identifier nodes which will be
  	   looked up by digest_init.  */
! 	process_index_p = !(type && IS_AGGR_TYPE (type));
  
! 	n = VEC_copy (constructor_elt, gc, CONSTRUCTOR_ELTS (t));
! 	for (idx = 0; VEC_iterate (constructor_elt, n, idx, ce); idx++)
! 	  {
! 	    if (ce->index && process_index_p)
! 	      ce->index = RECUR (ce->index);
! 	    ce->value = RECUR (ce->value);
  	  }
  
! 	r = build_constructor (NULL_TREE, n);
  	TREE_HAS_CONSTRUCTOR (r) = TREE_HAS_CONSTRUCTOR (t);
  
  	if (type)
! 	  return digest_init (type, r);
  	return r;
        }
  
Index: cp/rtti.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/rtti.c,v
retrieving revision 1.219
diff -c -p -r1.219 rtti.c
*** cp/rtti.c	25 Jun 2005 00:58:15 -0000	1.219
--- cp/rtti.c	9 Jul 2005 15:25:04 -0000
*************** tinfo_base_init (tinfo_s *ti, tree targe
*** 861,867 ****
  
    init = tree_cons (NULL_TREE, decay_conversion (name_decl), init);
  
!   init = build_constructor (NULL_TREE, nreverse (init));
    TREE_CONSTANT (init) = 1;
    TREE_INVARIANT (init) = 1;
    TREE_STATIC (init) = 1;
--- 861,867 ----
  
    init = tree_cons (NULL_TREE, decay_conversion (name_decl), init);
  
!   init = build_constructor_from_list (NULL_TREE, nreverse (init));
    TREE_CONSTANT (init) = 1;
    TREE_INVARIANT (init) = 1;
    TREE_STATIC (init) = 1;
*************** generic_initializer (tinfo_s *ti, tree t
*** 879,885 ****
  {
    tree init = tinfo_base_init (ti, target);
    
!   init = build_constructor (NULL_TREE, init);
    TREE_CONSTANT (init) = 1;
    TREE_INVARIANT (init) = 1;
    TREE_STATIC (init) = 1;
--- 879,885 ----
  {
    tree init = tinfo_base_init (ti, target);
    
!   init = build_constructor_from_list (NULL_TREE, init);
    TREE_CONSTANT (init) = 1;
    TREE_INVARIANT (init) = 1;
    TREE_STATIC (init) = 1;
*************** ptr_initializer (tinfo_s *ti, tree targe
*** 905,911 ****
  		    get_tinfo_ptr (TYPE_MAIN_VARIANT (to)),
  		    init);
  
!   init = build_constructor (NULL_TREE, nreverse (init));
    TREE_CONSTANT (init) = 1;
    TREE_INVARIANT (init) = 1;
    TREE_STATIC (init) = 1;
--- 905,911 ----
  		    get_tinfo_ptr (TYPE_MAIN_VARIANT (to)),
  		    init);
  
!   init = build_constructor_from_list (NULL_TREE, nreverse (init));
    TREE_CONSTANT (init) = 1;
    TREE_INVARIANT (init) = 1;
    TREE_STATIC (init) = 1;
*************** ptm_initializer (tinfo_s *ti, tree targe
*** 937,944 ****
    init = tree_cons (NULL_TREE,
  		    get_tinfo_ptr (klass),
  		    init);
! 
!   init = build_constructor (NULL_TREE, nreverse (init));
    TREE_CONSTANT (init) = 1;
    TREE_INVARIANT (init) = 1;
    TREE_STATIC (init) = 1;
--- 937,944 ----
    init = tree_cons (NULL_TREE,
  		    get_tinfo_ptr (klass),
  		    init);
!   
!   init = build_constructor_from_list (NULL_TREE, nreverse (init));
    TREE_CONSTANT (init) = 1;
    TREE_INVARIANT (init) = 1;
    TREE_STATIC (init) = 1;
*************** class_initializer (tinfo_s *ti, tree tar
*** 955,961 ****
    tree init = tinfo_base_init (ti, target);
  
    TREE_CHAIN (init) = trail;
!   init = build_constructor (NULL_TREE, init);
    TREE_CONSTANT (init) = 1;
    TREE_INVARIANT (init) = 1;
    TREE_STATIC (init) = 1;
--- 955,961 ----
    tree init = tinfo_base_init (ti, target);
  
    TREE_CHAIN (init) = trail;
!   init = build_constructor_from_list (NULL_TREE, init);
    TREE_CONSTANT (init) = 1;
    TREE_INVARIANT (init) = 1;
    TREE_STATIC (init) = 1;
*************** get_pseudo_ti_init (tree type, unsigned 
*** 1066,1075 ****
  					 build_int_cst (NULL_TREE, flags));
  	    base_init = tree_cons (NULL_TREE, offset, base_init);
  	    base_init = tree_cons (NULL_TREE, tinfo, base_init);
! 	    base_init = build_constructor (NULL_TREE, base_init);
  	    base_inits = tree_cons (NULL_TREE, base_init, base_inits);
  	  }
! 	base_inits = build_constructor (NULL_TREE, base_inits);
  	base_inits = tree_cons (NULL_TREE, base_inits, NULL_TREE);
  	/* Prepend the number of bases.  */
  	base_inits = tree_cons (NULL_TREE,
--- 1066,1075 ----
  					 build_int_cst (NULL_TREE, flags));
  	    base_init = tree_cons (NULL_TREE, offset, base_init);
  	    base_init = tree_cons (NULL_TREE, tinfo, base_init);
! 	    base_init = build_constructor_from_list (NULL_TREE, base_init);
  	    base_inits = tree_cons (NULL_TREE, base_init, base_inits);
  	  }
! 	base_inits = build_constructor_from_list (NULL_TREE, base_inits);
  	base_inits = tree_cons (NULL_TREE, base_inits, NULL_TREE);
  	/* Prepend the number of bases.  */
  	base_inits = tree_cons (NULL_TREE,
Index: cp/semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/semantics.c,v
retrieving revision 1.480
diff -c -p -r1.480 semantics.c
*** cp/semantics.c	2 Jul 2005 10:54:58 -0000	1.480
--- cp/semantics.c	9 Jul 2005 15:25:05 -0000
*************** finish_unary_op_expr (enum tree_code cod
*** 2011,2030 ****
     the INITIALIZER_LIST is being cast.  */
  
  tree
! finish_compound_literal (tree type, tree initializer_list)
  {
    tree compound_literal;
  
    /* Build a CONSTRUCTOR for the INITIALIZER_LIST.  */
    compound_literal = build_constructor (NULL_TREE, initializer_list);
    /* Mark it as a compound-literal.  */
-   TREE_HAS_CONSTRUCTOR (compound_literal) = 1;
    if (processing_template_decl)
      TREE_TYPE (compound_literal) = type;
    else
      {
        /* Check the initialization.  */
!       compound_literal = digest_init (type, compound_literal, NULL);
        /* If the TYPE was an array type with an unknown bound, then we can
  	 figure out the dimension now.  For example, something like:
  
--- 2011,2029 ----
     the INITIALIZER_LIST is being cast.  */
  
  tree
! finish_compound_literal (tree type, VEC(constructor_elt,gc) *initializer_list)
  {
    tree compound_literal;
  
    /* Build a CONSTRUCTOR for the INITIALIZER_LIST.  */
    compound_literal = build_constructor (NULL_TREE, initializer_list);
    /* Mark it as a compound-literal.  */
    if (processing_template_decl)
      TREE_TYPE (compound_literal) = type;
    else
      {
        /* Check the initialization.  */
!       compound_literal = digest_init (type, compound_literal);
        /* If the TYPE was an array type with an unknown bound, then we can
  	 figure out the dimension now.  For example, something like:
  
*************** finish_compound_literal (tree type, tree
*** 2036,2041 ****
--- 2035,2041 ----
  				compound_literal, 1);
      }
  
+   TREE_HAS_CONSTRUCTOR (compound_literal) = 1;
    return compound_literal;
  }
  
Index: cp/tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/tree.c,v
retrieving revision 1.439
diff -c -p -r1.439 tree.c
*** cp/tree.c	8 Jul 2005 23:37:04 -0000	1.439
--- cp/tree.c	9 Jul 2005 15:25:06 -0000
*************** stabilize_init (tree init, tree *initp)
*** 2236,2242 ****
        if (TREE_CODE (t) == COMPOUND_EXPR)
  	t = expr_last (t);
        if (TREE_CODE (t) == CONSTRUCTOR
! 	  && CONSTRUCTOR_ELTS (t) == NULL_TREE)
  	{
  	  /* Default-initialization.  */
  	  *initp = NULL_TREE;
--- 2236,2242 ----
        if (TREE_CODE (t) == COMPOUND_EXPR)
  	t = expr_last (t);
        if (TREE_CODE (t) == CONSTRUCTOR
! 	  && EMPTY_CONSTRUCTOR_P (t))
  	{
  	  /* Default-initialization.  */
  	  *initp = NULL_TREE;
Index: cp/typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/typeck.c,v
retrieving revision 1.642
diff -c -p -r1.642 typeck.c
*** cp/typeck.c	2 Jul 2005 10:54:59 -0000	1.642
--- cp/typeck.c	9 Jul 2005 15:25:07 -0000
*************** build_ptrmemfunc1 (tree type, tree delta
*** 5641,5646 ****
--- 5641,5647 ----
    tree u = NULL_TREE;
    tree delta_field;
    tree pfn_field;
+   VEC(constructor_elt, gc) *v;
  
    /* Pull the FIELD_DECLs out of the type.  */
    pfn_field = TYPE_FIELDS (type);
*************** build_ptrmemfunc1 (tree type, tree delta
*** 5650,5658 ****
    delta = convert_and_check (delta_type_node, delta);
  
    /* Finish creating the initializer.  */
!   u = tree_cons (pfn_field, pfn,
! 		 build_tree_list (delta_field, delta));
!   u = build_constructor (type, u);
    TREE_CONSTANT (u) = TREE_CONSTANT (pfn) & TREE_CONSTANT (delta);
    TREE_INVARIANT (u) = TREE_INVARIANT (pfn) & TREE_INVARIANT (delta);
    TREE_STATIC (u) = (TREE_CONSTANT (u)
--- 5651,5660 ----
    delta = convert_and_check (delta_type_node, delta);
  
    /* Finish creating the initializer.  */
!   v = VEC_alloc(constructor_elt, gc, 2);
!   CONSTRUCTOR_APPEND_ELT(v, pfn_field, pfn);
!   CONSTRUCTOR_APPEND_ELT(v, delta_field, delta);
!   u = build_constructor (type, v);
    TREE_CONSTANT (u) = TREE_CONSTANT (pfn) & TREE_CONSTANT (delta);
    TREE_INVARIANT (u) = TREE_INVARIANT (pfn) & TREE_INVARIANT (delta);
    TREE_STATIC (u) = (TREE_CONSTANT (u)
Index: cp/typeck2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/typeck2.c,v
retrieving revision 1.190
diff -c -p -r1.190 typeck2.c
*** cp/typeck2.c	2 Jul 2005 10:55:02 -0000	1.190
--- cp/typeck2.c	9 Jul 2005 15:25:08 -0000
*************** Boston, MA 02110-1301, USA.  */
*** 39,45 ****
  #include "output.h"
  #include "diagnostic.h"
  
! static tree process_init_constructor (tree, tree, tree *);
  
  /* Print an error message stemming from an attempt to use
     BASETYPE as a base class for TYPE.  */
--- 39,47 ----
  #include "output.h"
  #include "diagnostic.h"
  
! static tree
! process_init_constructor (tree type, tree init);
! 
  
  /* Print an error message stemming from an attempt to use
     BASETYPE as a base class for TYPE.  */
*************** cxx_incomplete_type_error (tree value, t
*** 435,445 ****
  static void
  split_nonconstant_init_1 (tree dest, tree init)
  {
!   tree *pelt, elt, type = TREE_TYPE (dest);
!   tree sub, code, inner_type = NULL;
    bool array_type_p = false;
  
-   pelt = &CONSTRUCTOR_ELTS (init);
    switch (TREE_CODE (type))
      {
      case ARRAY_TYPE:
--- 437,448 ----
  static void
  split_nonconstant_init_1 (tree dest, tree init)
  {
!   unsigned HOST_WIDE_INT idx;
!   tree field_index, value;
!   tree type = TREE_TYPE (dest);
!   tree inner_type = NULL;
    bool array_type_p = false;
  
    switch (TREE_CODE (type))
      {
      case ARRAY_TYPE:
*************** split_nonconstant_init_1 (tree dest, tre
*** 450,465 ****
      case RECORD_TYPE:
      case UNION_TYPE:
      case QUAL_UNION_TYPE:
!       while ((elt = *pelt))
  	{
! 	  tree field_index = TREE_PURPOSE (elt);
! 	  tree value = TREE_VALUE (elt);
  
  	  if (!array_type_p)
  	    inner_type = TREE_TYPE (field_index);
  
  	  if (TREE_CODE (value) == CONSTRUCTOR)
  	    {
  	      if (array_type_p)
  		sub = build4 (ARRAY_REF, inner_type, dest, field_index,
  			      NULL_TREE, NULL_TREE);
--- 453,473 ----
      case RECORD_TYPE:
      case UNION_TYPE:
      case QUAL_UNION_TYPE:
!       FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (init), idx,
! 				field_index, value)
  	{
! 	  /* The current implementation of this algorithm assumes that
! 	     the field was set for all the elements. This is usually done
! 	     by process_init_constructor.  */
! 	  gcc_assert (field_index);
  
  	  if (!array_type_p)
  	    inner_type = TREE_TYPE (field_index);
  
  	  if (TREE_CODE (value) == CONSTRUCTOR)
  	    {
+ 	      tree sub;
+ 
  	      if (array_type_p)
  		sub = build4 (ARRAY_REF, inner_type, dest, field_index,
  			      NULL_TREE, NULL_TREE);
*************** split_nonconstant_init_1 (tree dest, tre
*** 471,477 ****
  	    }
  	  else if (!initializer_constant_valid_p (value, inner_type))
  	    {
! 	      *pelt = TREE_CHAIN (elt);
  
  	      if (array_type_p)
  		sub = build4 (ARRAY_REF, inner_type, dest, field_index,
--- 479,497 ----
  	    }
  	  else if (!initializer_constant_valid_p (value, inner_type))
  	    {
! 	      tree code;
! 	      tree sub;
! 
! 	      /* FIXME: Ordered removal is O(1) so the whole function is
! 		 worst-case quadratic. This could be fixed using an aside
! 		 bitmap to record which elements must be removed and remove
! 		 them all at the same time. Or by merging
! 		 split_non_constant_init into process_init_constructor_array,
! 		 that is separating constants from non-constants while building
! 		 the vector.  */
! 	      VEC_ordered_remove (constructor_elt, CONSTRUCTOR_ELTS (init),
! 				  idx);
! 	      --idx;
  
  	      if (array_type_p)
  		sub = build4 (ARRAY_REF, inner_type, dest, field_index,
*************** split_nonconstant_init_1 (tree dest, tre
*** 485,498 ****
  	      add_stmt (code);
  	      continue;
  	    }
- 
- 	  pelt = &TREE_CHAIN (elt);
  	}
        break;
  
      case VECTOR_TYPE:
        if (!initializer_constant_valid_p (init, type))
  	{
  	  tree cons = copy_node (init);
  	  CONSTRUCTOR_ELTS (init) = NULL;
  	  code = build2 (MODIFY_EXPR, type, dest, cons);
--- 505,517 ----
  	      add_stmt (code);
  	      continue;
  	    }
  	}
        break;
  
      case VECTOR_TYPE:
        if (!initializer_constant_valid_p (init, type))
  	{
+ 	  tree code;
  	  tree cons = copy_node (init);
  	  CONSTRUCTOR_ELTS (init) = NULL;
  	  code = build2 (MODIFY_EXPR, type, dest, cons);
*************** store_init_value (tree decl, tree init)
*** 568,574 ****
  	{
  	  error ("constructor syntax used, but no constructor declared "
  		 "for type %qT", type);
! 	  init = build_constructor (NULL_TREE, nreverse (init));
  	}
      }
    else if (TREE_CODE (init) == TREE_LIST
--- 587,593 ----
  	{
  	  error ("constructor syntax used, but no constructor declared "
  		 "for type %qT", type);
! 	  init = build_constructor_from_list (NULL_TREE, nreverse (init));
  	}
      }
    else if (TREE_CODE (init) == TREE_LIST
*************** store_init_value (tree decl, tree init)
*** 591,597 ****
    /* End of special C++ code.  */
  
    /* Digest the specified initializer into an expression.  */
!   value = digest_init (type, init, (tree *) 0);
    /* If the initializer is not a constant, fill in DECL_INITIAL with
       the bits that are constant, and then return an expression that
       will perform the dynamic initialization.  */
--- 610,616 ----
    /* End of special C++ code.  */
  
    /* Digest the specified initializer into an expression.  */
!   value = digest_init (type, init);
    /* If the initializer is not a constant, fill in DECL_INITIAL with
       the bits that are constant, and then return an expression that
       will perform the dynamic initialization.  */
*************** store_init_value (tree decl, tree init)
*** 607,645 ****
  }
  
  
! /* Digest the parser output INIT as an initializer for type TYPE.
!    Return a C expression of type TYPE to represent the initial value.
  
!    If TAIL is nonzero, it points to a variable holding a list of elements
!    of which INIT is the first.  We update the list stored there by
!    removing from the head all the elements that we use.
!    Normally this is only one; we use more than one element only if
!    TYPE is an aggregate and INIT is not a constructor.  */
  
  tree
! digest_init (tree type, tree init, tree* tail)
  {
    enum tree_code code = TREE_CODE (type);
-   tree element = NULL_TREE;
-   tree old_tail_contents = NULL_TREE;
- 
-   /* By default, assume we use one element from a list.
-      We correct this later in the sole case where it is not true.  */
- 
-   if (tail)
-     {
-       old_tail_contents = *tail;
-       *tail = TREE_CHAIN (*tail);
-     }
  
!   if (init == error_mark_node || (TREE_CODE (init) == TREE_LIST
! 				  && TREE_VALUE (init) == error_mark_node))
      return error_mark_node;
  
!   if (TREE_CODE (init) == ERROR_MARK)
!     /* __PRETTY_FUNCTION__'s initializer is a bogus expression inside
!        a template function. This gets substituted during instantiation.  */
!     return init;
  
    /* We must strip the outermost array type when completing the type,
       because the its bounds might be incomplete at the moment.  */
--- 626,647 ----
  }
  
  
! /* Process the initializer INIT for a variable of type TYPE, emitting
!    diagnostics for invalid initializers and converting the initializer as
!    appropriate.
  
!    For aggregate types, it assumes that reshape_init has already run, thus the
!    initializer will have the right shape (brace elision has been undone).  */
  
  tree
! digest_init (tree type, tree init)
  {
    enum tree_code code = TREE_CODE (type);
  
!   if (init == error_mark_node)
      return error_mark_node;
  
!   gcc_assert (init);
  
    /* We must strip the outermost array type when completing the type,
       because the its bounds might be incomplete at the moment.  */
*************** digest_init (tree type, tree init, tree*
*** 647,706 ****
  			      ? TREE_TYPE (type) : type, NULL_TREE))
      return error_mark_node;
  
!   /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
    if (TREE_CODE (init) == NON_LVALUE_EXPR)
      init = TREE_OPERAND (init, 0);
  
!   if (BRACE_ENCLOSED_INITIALIZER_P (init)
!       && CONSTRUCTOR_ELTS (init) != 0
!       && TREE_CHAIN (CONSTRUCTOR_ELTS (init)) == 0)
!     {
!       element = TREE_VALUE (CONSTRUCTOR_ELTS (init));
!       /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
!       if (element && TREE_CODE (element) == NON_LVALUE_EXPR)
! 	element = TREE_OPERAND (element, 0);
!       if (element == error_mark_node)
! 	return element;
!     }
! 
!   /* Initialization of an array of chars from a string constant
!      optionally enclosed in braces.  */
! 
    if (code == ARRAY_TYPE)
      {
!       tree typ1;
! 
!       if (TREE_CODE (init) == TREE_LIST)
! 	{
! 	  error ("initializing array with parameter list");
! 	  return error_mark_node;
! 	}
! 
!       typ1 = TYPE_MAIN_VARIANT (TREE_TYPE (type));
        if (char_type_p (typ1)
! 	  && ((init && TREE_CODE (init) == STRING_CST)
! 	      || (element && TREE_CODE (element) == STRING_CST)))
  	{
! 	  tree string = element ? element : init;
  
! 	  if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (string)))
! 	       != char_type_node)
  	      && TYPE_PRECISION (typ1) == BITS_PER_UNIT)
  	    {
  	      error ("char-array initialized from wide string");
  	      return error_mark_node;
  	    }
! 	  if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (string)))
! 	       == char_type_node)
  	      && TYPE_PRECISION (typ1) != BITS_PER_UNIT)
  	    {
  	      error ("int-array initialized from non-wide string");
  	      return error_mark_node;
  	    }
  
! 	  TREE_TYPE (string) = type;
! 	  if (TYPE_DOMAIN (type) != 0
! 	      && TREE_CONSTANT (TYPE_SIZE (type)))
  	    {
  	      int size = TREE_INT_CST_LOW (TYPE_SIZE (type));
  	      size = (size + BITS_PER_UNIT - 1) / BITS_PER_UNIT;
--- 649,686 ----
  			      ? TREE_TYPE (type) : type, NULL_TREE))
      return error_mark_node;
  
!   /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue
!      (g++.old-deja/g++.law/casts2.C).  */
    if (TREE_CODE (init) == NON_LVALUE_EXPR)
      init = TREE_OPERAND (init, 0);
  
!   /* Initialization of an array of chars from a string constant. The initializer
!      can be optionally enclosed in braces, but reshape_init has already removed
!      them if they were present.  */
    if (code == ARRAY_TYPE)
      {
!       tree typ1 = TYPE_MAIN_VARIANT (TREE_TYPE (type));
        if (char_type_p (typ1)
! 	  /*&& init */
! 	  && TREE_CODE (init) == STRING_CST)
  	{
! 	  tree char_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (init)));
  
! 	  if (char_type != char_type_node
  	      && TYPE_PRECISION (typ1) == BITS_PER_UNIT)
  	    {
  	      error ("char-array initialized from wide string");
  	      return error_mark_node;
  	    }
! 	  if (char_type == char_type_node
  	      && TYPE_PRECISION (typ1) != BITS_PER_UNIT)
  	    {
  	      error ("int-array initialized from non-wide string");
  	      return error_mark_node;
  	    }
  
! 	  TREE_TYPE (init) = type;
! 	  if (TYPE_DOMAIN (type) != 0 && TREE_CONSTANT (TYPE_SIZE (type)))
  	    {
  	      int size = TREE_INT_CST_LOW (TYPE_SIZE (type));
  	      size = (size + BITS_PER_UNIT - 1) / BITS_PER_UNIT;
*************** digest_init (tree type, tree init, tree*
*** 708,1126 ****
  		 because it's ok to ignore the terminating null char that is
  		 counted in the length of the constant, but in C++ this would
  		 be invalid.  */
! 	      if (size < TREE_STRING_LENGTH (string))
  		pedwarn ("initializer-string for array of chars is too long");
  	    }
! 	  return string;
  	}
      }
  
    /* Handle scalar types, including conversions,
       and signature pointers and references.  */
  
!   if (code == INTEGER_TYPE || code == REAL_TYPE || code == POINTER_TYPE
!       || code == ENUMERAL_TYPE || code == REFERENCE_TYPE
!       || code == BOOLEAN_TYPE || code == COMPLEX_TYPE
!       || TYPE_PTR_TO_MEMBER_P (type))
      {
!       if (BRACE_ENCLOSED_INITIALIZER_P (init))
  	{
! 	  if (element == 0)
! 	    {
! 	      error ("initializer for scalar variable requires one element");
! 	      return error_mark_node;
! 	    }
! 	  init = element;
! 	}
!       while (BRACE_ENCLOSED_INITIALIZER_P (init))
! 	{
! 	  pedwarn ("braces around scalar initializer for %qT", type);
! 	  init = CONSTRUCTOR_ELTS (init);
! 	  if (TREE_CHAIN (init))
! 	    pedwarn ("ignoring extra initializers for %qT", type);
! 	  init = TREE_VALUE (init);
! 	}
  
!       return convert_for_initialization (0, type, init, LOOKUP_NORMAL,
  					 "initialization", NULL_TREE, 0);
      }
  
!   /* Come here only for records and arrays (and unions with constructors).  */
  
!   if (COMPLETE_TYPE_P (type) && ! TREE_CONSTANT (TYPE_SIZE (type)))
!     {
!       error ("variable-sized object of type %qT may not be initialized",
! 		type);
!       return error_mark_node;
      }
  
!   if (code == ARRAY_TYPE || code == VECTOR_TYPE || IS_AGGR_TYPE_CODE (code))
      {
!       if (BRACE_ENCLOSED_INITIALIZER_P (init))
  	{
! 	  if (TYPE_NON_AGGREGATE_CLASS (type))
! 	    {
! 	      error ("subobject of type %qT must be initialized by "
! 		     "constructor, not by %qE",
! 		     type, init);
! 	      return error_mark_node;
! 	    }
! 	  return process_init_constructor (type, init, (tree *)0);
! 	}
!       else if (can_convert_arg (type, TREE_TYPE (init), init)
! 	       || TYPE_NON_AGGREGATE_CLASS (type))
! 	/* These are never initialized from multiple constructor elements.  */;
!       else if (tail != 0)
! 	{
! 	  *tail = old_tail_contents;
! 	  return process_init_constructor (type, 0, tail);
  	}
  
!       if (code != ARRAY_TYPE)
! 	{
! 	  int flags = LOOKUP_NORMAL;
! 	  /* Initialization from { } is copy-initialization.  */
! 	  if (tail)
! 	    flags |= LOOKUP_ONLYCONVERTING;
! 
! 	  return convert_for_initialization (NULL_TREE, type, init, flags,
! 					     "initialization", NULL_TREE, 0);
! 	}
!     }
  
!   error ("invalid initializer");
!   return error_mark_node;
  }
- 
- /* Process a constructor for a variable of type TYPE.
-    The constructor elements may be specified either with INIT or with ELTS,
-    only one of which should be non-null.
- 
-    If INIT is specified, it is a CONSTRUCTOR node which is specifically
-    and solely for initializing this datum.
- 
-    If ELTS is specified, it is the address of a variable containing
-    a list of expressions.  We take as many elements as we need
-    from the head of the list and update the list.
- 
-    In the resulting constructor, TREE_CONSTANT is set if all elts are
-    constant, and TREE_STATIC is set if, in addition, all elts are simple enough
-    constants that the assembler and linker can compute them.  */
  
! static tree
! process_init_constructor (tree type, tree init, tree* elts)
  {
!   tree tail;
!   /* List of the elements of the result constructor,
!      in reverse order.  */
!   tree members = NULL;
!   tree next1;
!   tree result;
!   int allconstant = 1;
!   int allsimple = 1;
!   int erroneous = 0;
! 
!   /* Make TAIL be the list of elements to use for the initialization,
!      no matter how the data was given to us.  */
! 
!   if (elts)
!     {
!       if (warn_missing_braces)
! 	warning (0, "aggregate has a partly bracketed initializer");
!       tail = *elts;
!     }
!   else
!     tail = CONSTRUCTOR_ELTS (init);
  
!   /* Gobble as many elements as needed, and make a constructor or initial value
!      for each element of this aggregate.  Chain them together in result.
!      If there are too few, use 0 for each scalar ultimate component.  */
  
!   if (TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == VECTOR_TYPE)
      {
!       long len;
!       int i;
  
!       if (TREE_CODE (type) == ARRAY_TYPE)
  	{
! 	  tree domain = TYPE_DOMAIN (type);
! 	  if (domain)
! 	    len = (TREE_INT_CST_LOW (TYPE_MAX_VALUE (domain))
! 		   - TREE_INT_CST_LOW (TYPE_MIN_VALUE (domain))
! 		   + 1);
! 	  else
! 	    len = -1;  /* Take as many as there are.  */
! 	}
!       else
! 	{
! 	  /* Vectors are like simple fixed-size arrays.  */
! 	  len = TYPE_VECTOR_SUBPARTS (type);
  	}
  
!       for (i = 0; len < 0 || i < len; i++)
  	{
! 	  if (tail)
  	    {
! 	      if (TREE_PURPOSE (tail)
! 		  && (TREE_CODE (TREE_PURPOSE (tail)) != INTEGER_CST
! 		      || compare_tree_int (TREE_PURPOSE (tail), i) != 0))
! 		sorry ("non-trivial labeled initializers");
! 
! 	      if (TREE_VALUE (tail) != 0)
! 		{
! 		  tree tail1 = tail;
! 		  next1 = digest_init (TREE_TYPE (type),
! 				       TREE_VALUE (tail), &tail1);
! 		  if (next1 == error_mark_node)
! 		    return next1;
! 		  gcc_assert (same_type_ignoring_top_level_qualifiers_p
! 			      (TREE_TYPE (type), TREE_TYPE (next1)));
! 		  gcc_assert (!tail1 || TREE_CODE (tail1) == TREE_LIST);
! 		  if (tail == tail1 && len < 0)
! 		    {
! 		      error ("non-empty initializer for array of empty elements");
! 		      /* Just ignore what we were supposed to use.  */
! 		      tail1 = NULL_TREE;
! 		    }
! 		  tail = tail1;
! 		}
! 	      else
! 		{
! 		  next1 = error_mark_node;
! 		  tail = TREE_CHAIN (tail);
! 		}
  	    }
- 	  else if (len < 0)
- 	    /* We're done.  */
- 	    break;
- 	  else if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (type)))
- 	    {
- 	      /* If this type needs constructors run for
- 		 default-initialization, we can't rely on the backend to do it
- 		 for us, so build up TARGET_EXPRs.  If the type in question is
- 		 a class, just build one up; if it's an array, recurse.  */
  
! 	      if (IS_AGGR_TYPE (TREE_TYPE (type)))
! 		next1 = build_functional_cast (TREE_TYPE (type), NULL_TREE);
! 	      else
! 		next1 = build_constructor (NULL_TREE, NULL_TREE);
! 	      next1 = digest_init (TREE_TYPE (type), next1, 0);
! 	    }
! 	  else if (! zero_init_p (TREE_TYPE (type)))
! 	    next1 = build_zero_init (TREE_TYPE (type),
! 				     /*nelts=*/NULL_TREE,
! 				     /*static_storage_p=*/false);
  	  else
! 	    /* The default zero-initialization is fine for us; don't
! 	       add anything to the CONSTRUCTOR.  */
! 	    break;
  
! 	  if (next1 == error_mark_node)
! 	    erroneous = 1;
! 	  else if (!TREE_CONSTANT (next1))
! 	    allconstant = 0;
! 	  else if (! initializer_constant_valid_p (next1, TREE_TYPE (next1)))
! 	    allsimple = 0;
! 	  members = tree_cons (size_int (i), next1, members);
! 	}
!     }
!   else if (TREE_CODE (type) == RECORD_TYPE)
!     {
!       tree field;
  
!       if (tail)
  	{
! 	  gcc_assert (!CLASSTYPE_VBASECLASSES (type));
! 	  gcc_assert (!TYPE_BINFO (type)
! 		      || !BINFO_N_BASE_BINFOS (TYPE_BINFO (type)));
! 	  gcc_assert (!TYPE_POLYMORPHIC_P (type));
  	}
  
!       for (field = TYPE_FIELDS (type); field;
! 	   field = TREE_CHAIN (field))
! 	{
! 	  if (! DECL_NAME (field) && DECL_C_BIT_FIELD (field))
! 	    {
! 	      members = tree_cons (field, integer_zero_node, members);
! 	      continue;
! 	    }
  
! 	  if (TREE_CODE (field) != FIELD_DECL || DECL_ARTIFICIAL (field))
! 	    continue;
  
! 	  if (tail)
! 	    {
! 	      if (TREE_PURPOSE (tail)
! 		  && TREE_PURPOSE (tail) != field
! 		  && TREE_PURPOSE (tail) != DECL_NAME (field))
! 		sorry ("non-trivial labeled initializers");
! 
! 	      if (TREE_VALUE (tail) != 0)
! 		{
! 		  tree tail1 = tail;
! 
! 		  next1 = digest_init (TREE_TYPE (field),
! 				       TREE_VALUE (tail), &tail1);
! 		  gcc_assert (!tail1 || TREE_CODE (tail1) == TREE_LIST);
! 		  tail = tail1;
! 		}
! 	      else
! 		{
! 		  next1 = error_mark_node;
! 		  tail = TREE_CHAIN (tail);
! 		}
! 	    }
! 	  else if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (field)))
! 	    {
! 	      /* If this type needs constructors run for
! 		 default-initialization, we can't rely on the backend to do it
! 		 for us, so build up TARGET_EXPRs.  If the type in question is
! 		 a class, just build one up; if it's an array, recurse.  */
! 
! 	      if (IS_AGGR_TYPE (TREE_TYPE (field)))
! 		next1 = build_functional_cast (TREE_TYPE (field),
! 					       NULL_TREE);
! 	      else
! 		{
! 		  next1 = build_constructor (NULL_TREE, NULL_TREE);
! 		  if (init)
! 		    TREE_HAS_CONSTRUCTOR (next1)
! 		       = TREE_HAS_CONSTRUCTOR (init);
! 		}
! 	      next1 = digest_init (TREE_TYPE (field), next1, 0);
! 
! 	      /* Warn when some struct elements are implicitly initialized.  */
! 	      if (warn_missing_field_initializers
! 		  && (!init || BRACE_ENCLOSED_INITIALIZER_P (init)))
! 		warning (0, "missing initializer for member %qD", field);
! 	    }
! 	  else
  	    {
! 	      if (TREE_READONLY (field))
! 		error ("uninitialized const member %qD", field);
! 	      else if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (TREE_TYPE (field)))
! 		error ("member %qD with uninitialized const fields", field);
! 	      else if (TREE_CODE (TREE_TYPE (field)) == REFERENCE_TYPE)
! 		error ("member %qD is uninitialized reference", field);
! 
! 	      /* Warn when some struct elements are implicitly initialized
! 		 to zero.  */
! 	      if (warn_missing_field_initializers
! 		  && (!init || BRACE_ENCLOSED_INITIALIZER_P (init)))
! 		warning (0, "missing initializer for member %qD", field);
! 
! 	      if (! zero_init_p (TREE_TYPE (field)))
! 		next1 = build_zero_init (TREE_TYPE (field),
! 					 /*nelts=*/NULL_TREE,
! 					 /*static_storage_p=*/false);
! 	      else
! 		/* The default zero-initialization is fine for us; don't
! 		   add anything to the CONSTRUCTOR.  */
! 		continue;
  	    }
! 
! 	  if (next1 == error_mark_node)
! 	    erroneous = 1;
! 	  else if (!TREE_CONSTANT (next1))
! 	    allconstant = 0;
! 	  else if (! initializer_constant_valid_p (next1, TREE_TYPE (next1)))
! 	    allsimple = 0;
! 	  members = tree_cons (field, next1, members);
  	}
      }
!   else if (TREE_CODE (type) == UNION_TYPE
! 	   /* If the initializer was empty, use default zero initialization.  */
! 	   && tail)
      {
-       tree field = TYPE_FIELDS (type);
- 
        /* Find the first named field.  ANSI decided in September 1990
  	 that only named fields count here.  */
        while (field && (!DECL_NAME (field) || TREE_CODE (field) != FIELD_DECL))
  	field = TREE_CHAIN (field);
! 
!       /* If this element specifies a field, initialize via that field.  */
!       if (TREE_PURPOSE (tail) != NULL_TREE)
! 	{
! 	  int win = 0;
! 
! 	  if (TREE_CODE (TREE_PURPOSE (tail)) == FIELD_DECL)
! 	    /* Handle the case of a call by build_c_cast.  */
! 	    field = TREE_PURPOSE (tail), win = 1;
! 	  else if (TREE_CODE (TREE_PURPOSE (tail)) != IDENTIFIER_NODE)
! 	    error ("index value instead of field name in union initializer");
! 	  else
! 	    {
! 	      tree temp;
! 	      for (temp = TYPE_FIELDS (type);
! 		   temp;
! 		   temp = TREE_CHAIN (temp))
! 		if (DECL_NAME (temp) == TREE_PURPOSE (tail))
! 		  break;
! 	      if (temp)
! 		field = temp, win = 1;
! 	      else
! 		error ("no field %qD in union being initialized",
! 		       TREE_PURPOSE (tail));
! 	    }
! 	  if (!win)
! 	    TREE_VALUE (tail) = error_mark_node;
! 	}
!       else if (field == 0)
  	{
  	  error ("union %qT with no named members cannot be initialized",
  		 type);
! 	  TREE_VALUE (tail) = error_mark_node;
  	}
  
!       if (TREE_VALUE (tail) != 0)
! 	{
! 	  tree tail1 = tail;
  
! 	  next1 = digest_init (TREE_TYPE (field),
! 			       TREE_VALUE (tail), &tail1);
! 	  gcc_assert (!tail1 || TREE_CODE (tail1) == TREE_LIST);
! 	  tail = tail1;
! 	}
!       else
! 	{
! 	  next1 = error_mark_node;
! 	  tail = TREE_CHAIN (tail);
! 	}
  
!       if (next1 == error_mark_node)
! 	erroneous = 1;
!       else if (!TREE_CONSTANT (next1))
! 	allconstant = 0;
!       else if (initializer_constant_valid_p (next1, TREE_TYPE (next1)) == 0)
! 	allsimple = 0;
!       members = tree_cons (field, next1, members);
!     }
! 
!   /* If arguments were specified as a list, just remove the ones we used.  */
!   if (elts)
!     *elts = tail;
!   /* If arguments were specified as a constructor,
!      complain unless we used all the elements of the constructor.  */
!   else if (tail)
!     pedwarn ("excess elements in aggregate initializer");
  
!   if (erroneous)
      return error_mark_node;
  
!   result = build_constructor (type, nreverse (members));
    if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type) == NULL_TREE)
!     cp_complete_array_type (&TREE_TYPE (result), result, /*do_default=*/0);
!   if (init)
!     TREE_HAS_CONSTRUCTOR (result) = TREE_HAS_CONSTRUCTOR (init);
!   if (allconstant)
!     {
!       TREE_CONSTANT (result) = 1;
!       TREE_INVARIANT (result) = 1;
!       if (allsimple)
! 	TREE_STATIC (result) = 1;
      }
!   return result;
  }
  
  /* Given a structure or union value DATUM, construct and return
--- 688,1059 ----
  		 because it's ok to ignore the terminating null char that is
  		 counted in the length of the constant, but in C++ this would
  		 be invalid.  */
! 	      if (size < TREE_STRING_LENGTH (init))
  		pedwarn ("initializer-string for array of chars is too long");
  	    }
! 	  return init;
  	}
      }
  
    /* Handle scalar types, including conversions,
       and signature pointers and references.  */
+   if (SCALAR_TYPE_P (type)
+       || code == REFERENCE_TYPE)
+     return convert_for_initialization (0, type, init, LOOKUP_NORMAL,
+ 				       "initialization", NULL_TREE, 0);
+ 
+   /* Come here only for aggregates: records, arrays, unions, complex numbers
+      and vectors.  */
+   gcc_assert (TREE_CODE (type) == ARRAY_TYPE
+ 	      || TREE_CODE (type) == VECTOR_TYPE
+ 	      || TREE_CODE (type) == RECORD_TYPE
+ 	      || TREE_CODE (type) == UNION_TYPE
+ 	      || TREE_CODE (type) == COMPLEX_TYPE);
  
!   if (BRACE_ENCLOSED_INITIALIZER_P (init))
!       return process_init_constructor (type, init);
!   else
      {
!       if (TREE_HAS_CONSTRUCTOR (init)
! 	  && TREE_CODE (type) == ARRAY_TYPE)
  	{
! 	  error ("cannot initialize aggregate of type %qT with "
! 		 "a compound literal", type);
  
! 	  return error_mark_node;
! 	}
!       return convert_for_initialization (NULL_TREE, type, init,
! 					 LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING,
  					 "initialization", NULL_TREE, 0);
      }
+ }
  
! 
! /* Set of flags used within process_init_constructor to describe the
!    initializers.  */
! #define PICFLAG_ERRONEOUS 1
! #define PICFLAG_NOT_ALL_CONSTANT 2
! #define PICFLAG_NOT_ALL_SIMPLE 4
  
! /* Given an initializer INIT, return the flag (PICFLAG_*) which better
!    describe it.  */
! 
! static int
! picflag_from_initializer (tree init)
! {
!   if (init == error_mark_node)
!     return PICFLAG_ERRONEOUS;
!   else if (!TREE_CONSTANT (init))
!     return PICFLAG_NOT_ALL_CONSTANT;
!   else if (!initializer_constant_valid_p (init, TREE_TYPE (init)))
!     return PICFLAG_NOT_ALL_SIMPLE;
!   return 0;
! }
! 
! /* Subroutine of process_init_constructor, which will process an initializer
!    INIT for a array or vector of type TYPE. Returns the flags (PICFLAG_*) which
!    describe the initializers.  */
! 
! static int
! process_init_constructor_array (tree type, tree init)
! {
!   unsigned HOST_WIDE_INT i, len = 0;
!   int flags = 0;
!   bool unbounded = false;
!   constructor_elt *ce;
!   VEC(constructor_elt,gc) *v = CONSTRUCTOR_ELTS (init);
! 
!   gcc_assert (TREE_CODE (type) == ARRAY_TYPE
! 	      || TREE_CODE (type) == VECTOR_TYPE);
! 
!   if (TREE_CODE (type) == ARRAY_TYPE)
!     {
!       tree domain = TYPE_DOMAIN (type);
!       if (domain)
! 	len = (TREE_INT_CST_LOW (TYPE_MAX_VALUE (domain))
! 	      - TREE_INT_CST_LOW (TYPE_MIN_VALUE (domain))
! 	      + 1);
!       else
! 	unbounded = true;  /* Take as many as there are.  */
      }
+   else
+     /* Vectors are like simple fixed-size arrays.  */
+     len = TYPE_VECTOR_SUBPARTS (type);
+ 
+   /* There cannot be more initializers than needed (or reshape_init would
+      detect this before we do.  */
+   if (!unbounded)
+     gcc_assert (VEC_length (constructor_elt, v) <= len);
  
!   for (i = 0; VEC_iterate (constructor_elt, v, i, ce); ++i)
      {
!       if (ce->index)
  	{
! 	  gcc_assert (TREE_CODE (ce->index) == INTEGER_CST);
! 	  if (compare_tree_int (ce->index, i) != 0)
! 	    sorry ("non-trivial designated initializers not supported");
  	}
+       else
+ 	ce->index = size_int (i);
+       gcc_assert (ce->value);
+       ce->value = digest_init (TREE_TYPE (type), ce->value);
+ 
+       if (ce->value != error_mark_node)
+ 	gcc_assert (same_type_ignoring_top_level_qualifiers_p
+ 		      (TREE_TYPE (type), TREE_TYPE (ce->value)));
+ 
+       flags |= picflag_from_initializer (ce->value);
+     }
+ 
+   /* No more initializers. If the array is unbounded, we are done. Otherwise,
+      we must add initializers ourselves.  */
+   if (!unbounded)
+     for (; i < len; ++i)
+       {
+ 	tree next;
+ 
+ 	if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (type)))
+ 	  {
+ 	    /* If this type needs constructors run for default-initialization,
+ 	      we can't rely on the backend to do it for us, so build up
+ 	      TARGET_EXPRs.  If the type in question is a class, just build
+ 	      one up; if it's an array, recurse.  */
+ 	    if (IS_AGGR_TYPE (TREE_TYPE (type)))
+ 		next = build_functional_cast (TREE_TYPE (type), NULL_TREE);
+ 	    else
+ 		next = build_constructor (NULL_TREE, NULL);
+ 	    next = digest_init (TREE_TYPE (type), next);
+ 	  }
+ 	else if (!zero_init_p (TREE_TYPE (type)))
+ 	  next = build_zero_init (TREE_TYPE (type),
+ 				  /*nelts=*/NULL_TREE,
+ 				  /*static_storage_p=*/false);
+ 	else
+ 	  /* The default zero-initialization is fine for us; don't
+ 	     add anything to the CONSTRUCTOR.  */
+ 	  break;
  
! 	flags |= picflag_from_initializer (next);    
! 	CONSTRUCTOR_APPEND_ELT (v, size_int (i), next);
!       }
  
!   CONSTRUCTOR_ELTS (init) = v;
!   return flags;
  }
  
! /* Subroutine of process_init_constructor, which will process an initializer
!    INIT for a class of type TYPE. Returns the flags (PICFLAG_*) which describe
!    the initializers.  */
! 
! static int
! process_init_constructor_record (tree type, tree init)
  {
!   VEC(constructor_elt,gc) *v = NULL;
!   int flags = 0;
!   tree field;
!   unsigned HOST_WIDE_INT idx = 0;
  
!   gcc_assert (TREE_CODE (type) == RECORD_TYPE);
!   gcc_assert (!CLASSTYPE_VBASECLASSES (type));
!   gcc_assert (!TYPE_BINFO (type)
! 	      || !BINFO_N_BASE_BINFOS (TYPE_BINFO (type)));
!   gcc_assert (!TYPE_POLYMORPHIC_P (type));
  
!   /* Generally, we will always have an index for each initializer (which is
!      a FIELD_DECL, put by reshape_init), but compound literals don't go trough
!      reshape_init. So we need to handle both cases.  */
!   for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
      {
!       tree next;
  
!       if (!DECL_NAME (field) && DECL_C_BIT_FIELD (field))
  	{
! 	  flags |= picflag_from_initializer (integer_zero_node);
! 	  CONSTRUCTOR_APPEND_ELT (v, field, integer_zero_node);
! 	  continue;
  	}
  
!       if (TREE_CODE (field) != FIELD_DECL || DECL_ARTIFICIAL (field))
! 	continue;
! 
!       if (idx < VEC_length (constructor_elt, CONSTRUCTOR_ELTS (init)))
  	{
! 	  constructor_elt *ce = VEC_index (constructor_elt,
! 					   CONSTRUCTOR_ELTS (init), idx);
! 	  if (ce->index)
  	    {
! 	      /* We can have either a FIELD_DECL or an IDENTIFIER_NODE. The
! 		 latter case can happen in templates where lookup has to be
! 		 deferred.  */
! 	      gcc_assert (TREE_CODE (ce->index) == FIELD_DECL
! 			  || TREE_CODE (ce->index) == IDENTIFIER_NODE);
! 	      if (ce->index != field
! 	          && ce->index != DECL_NAME (field))
! 		sorry ("non-trivial designated initializers not supported");
  	    }
  
! 	  gcc_assert (ce->value);
! 	  next = digest_init (TREE_TYPE (field), ce->value);
! 	  ++idx;
! 	}
!       else if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (field)))
! 	{
! 	  /* If this type needs constructors run for
! 	     default-initialization, we can't rely on the backend to do it
! 	     for us, so build up TARGET_EXPRs.  If the type in question is
! 	     a class, just build one up; if it's an array, recurse.  */
! 	  if (IS_AGGR_TYPE (TREE_TYPE (field)))
! 	    next = build_functional_cast (TREE_TYPE (field), NULL_TREE);
  	  else
! 	    next = build_constructor (NULL_TREE, NULL);
  
! 	  next = digest_init (TREE_TYPE (field), next);
  
! 	  /* Warn when some struct elements are implicitly initialized.  */
! 	  warning (OPT_Wmissing_field_initializers,
! 		   "missing initializer for member %qD", field);
! 	}
!       else
  	{
! 	  if (TREE_READONLY (field))
! 	    error ("uninitialized const member %qD", field);
! 	  else if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (TREE_TYPE (field)))
! 	    error ("member %qD with uninitialized const fields", field);
! 	  else if (TREE_CODE (TREE_TYPE (field)) == REFERENCE_TYPE)
! 	    error ("member %qD is uninitialized reference", field);
! 
! 	  /* Warn when some struct elements are implicitly initialized
! 	     to zero.  */
! 	  warning (OPT_Wmissing_field_initializers,
! 		   "missing initializer for member %qD", field);
! 
! 	  if (!zero_init_p (TREE_TYPE (field)))
! 	    next = build_zero_init (TREE_TYPE (field), /*nelts=*/NULL_TREE,
! 				    /*static_storage_p=*/false);
! 	  else
! 	    /* The default zero-initialization is fine for us; don't
! 	    add anything to the CONSTRUCTOR.  */
! 	    continue;
  	}
  
!       flags |= picflag_from_initializer (next);
!       CONSTRUCTOR_APPEND_ELT (v, field, next);
!     }
  
!   CONSTRUCTOR_ELTS (init) = v;
!   return flags;
! }
  
! /* Subroutine of process_init_constructor, which will process a single
!    initializer INIT for an union of type TYPE. Returns the flags (PICFLAG_*)
!    which describe the initializer.  */
! 
! static int
! process_init_constructor_union (tree type, tree init)
! {
!   constructor_elt *ce;
! 
!   /* If the initializer was empty, use default zero initialization.  */
!   if (VEC_empty (constructor_elt, CONSTRUCTOR_ELTS (init)))
!     return 0;
! 
!   gcc_assert (VEC_length (constructor_elt, CONSTRUCTOR_ELTS (init)) == 1);
!   ce = VEC_index (constructor_elt, CONSTRUCTOR_ELTS (init), 0);
! 
!   /* If this element specifies a field, initialize via that field.  */
!   if (ce->index)
!     {
!       if (TREE_CODE (ce->index) == FIELD_DECL)
! 	;
!       else if (TREE_CODE (ce->index) == IDENTIFIER_NODE)
! 	{
! 	  /* This can happen within a cast, see g++.dg/opt/cse2.C.  */
! 	  tree name = ce->index;
! 	  tree field;
! 	  for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
! 	    if (DECL_NAME (field) == name)
! 	      break;
! 	  if (!field)
  	    {
! 	      error ("no field %qD found in union being initialized", field);
! 	      ce->value = error_mark_node;
  	    }
! 	  ce->index = field;
! 	}
!       else
! 	{
! 	  gcc_assert (TREE_CODE (ce->index) == INTEGER_CST
! 		      || TREE_CODE (ce->index) == RANGE_EXPR);
! 	  error ("index value instead of field name in union initializer");
! 	  ce->value = error_mark_node;
  	}
      }
!   else
      {
        /* Find the first named field.  ANSI decided in September 1990
  	 that only named fields count here.  */
+       tree field = TYPE_FIELDS (type);
        while (field && (!DECL_NAME (field) || TREE_CODE (field) != FIELD_DECL))
  	field = TREE_CHAIN (field);
!       if (!field)
  	{
  	  error ("union %qT with no named members cannot be initialized",
  		 type);
! 	  ce->value = error_mark_node;
  	}
+       ce->index = field;
+     }
  
!   if (ce->value && ce->value != error_mark_node)
!     ce->value = digest_init (TREE_TYPE (ce->index), ce->value);
  
!   return picflag_from_initializer (ce->value);
! }
! 
! /* Process INIT, a constructor for a variable of aggregate type TYPE. The
!    constructor is a brace-enclosed initializer, and will be modified in-place.
  
!    Each element is converted to the right type through digest_init, and
!    missing initializers are added following the language rules (zero-padding,
!    etc.).
  
!    After the execution, the initializer will have TREE_CONSTANT if all elts are
!    constant, and TREE_STATIC set if, in addition, all elts are simple enough
!    constants that the assembler and linker can compute them.
!    
!    The function returns the initializer itself, or error_mark_node in case
!    of error.  */
! 
! static tree
! process_init_constructor (tree type, tree init)
! {
!   int flags;
! 
!   gcc_assert (BRACE_ENCLOSED_INITIALIZER_P (init));
! 
!   if (TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == VECTOR_TYPE)
!     flags = process_init_constructor_array (type, init);
!   else if (TREE_CODE (type) == RECORD_TYPE)
!     flags = process_init_constructor_record (type, init);
!   else if (TREE_CODE (type) == UNION_TYPE)
!     flags = process_init_constructor_union (type, init);
!   else
!     gcc_unreachable ();
! 
!   if (flags & PICFLAG_ERRONEOUS)
      return error_mark_node;
  
!   TREE_TYPE (init) = type;
    if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type) == NULL_TREE)
!     cp_complete_array_type (&TREE_TYPE (init), init, /*do_default=*/0);
!   if (!(flags & PICFLAG_NOT_ALL_CONSTANT))
!     {
!       TREE_CONSTANT (init) = 1;
!       TREE_INVARIANT (init) = 1;
!       if (!(flags & PICFLAG_NOT_ALL_SIMPLE))
! 	TREE_STATIC (init) = 1;
      }
!   return init;
  }
  
  /* Given a structure or union value DATUM, construct and return
*************** build_functional_cast (tree exp, tree pa
*** 1396,1402 ****
    if (parms == NULL_TREE && !TYPE_NEEDS_CONSTRUCTING (type)
        && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
      {
!       exp = build_constructor (type, NULL_TREE);
        return get_target_expr (exp);
      }
  
--- 1329,1335 ----
    if (parms == NULL_TREE && !TYPE_NEEDS_CONSTRUCTING (type)
        && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
      {
!       exp = build_constructor (type, NULL);
        return get_target_expr (exp);
      }
  
Index: fortran/trans-array.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fortran/trans-array.c,v
retrieving revision 1.52
diff -c -p -r1.52 trans-array.c
*** fortran/trans-array.c	7 Jul 2005 01:55:53 -0000	1.52
--- fortran/trans-array.c	9 Jul 2005 15:25:09 -0000
*************** gfc_build_null_descriptor (tree type)
*** 299,306 ****
    field = TYPE_FIELDS (type);
  
    /* Set a NULL data pointer.  */
!   tmp = tree_cons (field, null_pointer_node, NULL_TREE);
!   tmp = build1 (CONSTRUCTOR, type, tmp);
    TREE_CONSTANT (tmp) = 1;
    TREE_INVARIANT (tmp) = 1;
    /* All other fields are ignored.  */
--- 299,305 ----
    field = TYPE_FIELDS (type);
  
    /* Set a NULL data pointer.  */
!   tmp = build_constructor_single (type, field, null_pointer_node);
    TREE_CONSTANT (tmp) = 1;
    TREE_INVARIANT (tmp) = 1;
    /* All other fields are ignored.  */
*************** gfc_trans_array_constructor_value (stmtb
*** 834,840 ****
  					  gfc_index_zero_node, bound);
  	      tmptype = build_array_type (type, tmptype);
  
! 	      init = build1 (CONSTRUCTOR, tmptype, nreverse (list));
  	      TREE_CONSTANT (init) = 1;
  	      TREE_INVARIANT (init) = 1;
  	      TREE_STATIC (init) = 1;
--- 833,839 ----
  					  gfc_index_zero_node, bound);
  	      tmptype = build_array_type (type, tmptype);
  
! 	      init = build_constructor_from_list (tmptype, nreverse (list));
  	      TREE_CONSTANT (init) = 1;
  	      TREE_INVARIANT (init) = 1;
  	      TREE_STATIC (init) = 1;
*************** tree
*** 2833,2847 ****
  gfc_conv_array_initializer (tree type, gfc_expr * expr)
  {
    gfc_constructor *c;
-   tree list;
    tree tmp;
    mpz_t maxval;
    gfc_se se;
    HOST_WIDE_INT hi;
    unsigned HOST_WIDE_INT lo;
    tree index, range;
  
-   list = NULL_TREE;
    switch (expr->expr_type)
      {
      case EXPR_CONSTANT:
--- 2832,2845 ----
  gfc_conv_array_initializer (tree type, gfc_expr * expr)
  {
    gfc_constructor *c;
    tree tmp;
    mpz_t maxval;
    gfc_se se;
    HOST_WIDE_INT hi;
    unsigned HOST_WIDE_INT lo;
    tree index, range;
+   VEC(constructor_elt,gc) *v = NULL;
  
    switch (expr->expr_type)
      {
      case EXPR_CONSTANT:
*************** gfc_conv_array_initializer (tree type, g
*** 2865,2871 ****
        /* This will probably eat buckets of memory for large arrays.  */
        while (hi != 0 || lo != 0)
          {
!           list = tree_cons (NULL_TREE, se.expr, list);
            if (lo == 0)
              hi--;
            lo--;
--- 2863,2869 ----
        /* This will probably eat buckets of memory for large arrays.  */
        while (hi != 0 || lo != 0)
          {
! 	  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, se.expr);
            if (lo == 0)
              hi--;
            lo--;
*************** gfc_conv_array_initializer (tree type, g
*** 2873,2879 ****
        break;
  
      case EXPR_ARRAY:
!       /* Create a list of all the elements.  */
        for (c = expr->value.constructor; c; c = c->next)
          {
            if (c->iterator)
--- 2871,2877 ----
        break;
  
      case EXPR_ARRAY:
!       /* Create a vector of all the elements.  */
        for (c = expr->value.constructor; c; c = c->next)
          {
            if (c->iterator)
*************** gfc_conv_array_initializer (tree type, g
*** 2917,2942 ****
  	    case EXPR_CONSTANT:
  	      gfc_conv_constant (&se, c->expr);
                if (range == NULL_TREE)
!                 list = tree_cons (index, se.expr, list);
                else
                  {
                    if (index != NULL_TREE)
!                     list = tree_cons (index, se.expr, list);
!                   list = tree_cons (range, se.expr, list);
                  }
  	      break;
  
  	    case EXPR_STRUCTURE:
                gfc_conv_structure (&se, c->expr, 1);
!               list = tree_cons (index, se.expr, list);
  	      break;
  
  	    default:
  	      gcc_unreachable ();
  	    }
          }
-       /* We created the list in reverse order.  */
-       list = nreverse (list);
        break;
  
      default:
--- 2915,2938 ----
  	    case EXPR_CONSTANT:
  	      gfc_conv_constant (&se, c->expr);
                if (range == NULL_TREE)
! 		CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
                else
                  {
                    if (index != NULL_TREE)
! 		    CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
! 		  CONSTRUCTOR_APPEND_ELT (v, range, se.expr);
                  }
  	      break;
  
  	    case EXPR_STRUCTURE:
                gfc_conv_structure (&se, c->expr, 1);
! 	      CONSTRUCTOR_APPEND_ELT (v, index, se.expr);
  	      break;
  
  	    default:
  	      gcc_unreachable ();
  	    }
          }
        break;
  
      default:
*************** gfc_conv_array_initializer (tree type, g
*** 2944,2950 ****
      }
  
    /* Create a constructor from the list of elements.  */
!   tmp = build1 (CONSTRUCTOR, type, list);
    TREE_CONSTANT (tmp) = 1;
    TREE_INVARIANT (tmp) = 1;
    return tmp;
--- 2940,2946 ----
      }
  
    /* Create a constructor from the list of elements.  */
!   tmp = build_constructor (type, v);
    TREE_CONSTANT (tmp) = 1;
    TREE_INVARIANT (tmp) = 1;
    return tmp;
Index: fortran/trans-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fortran/trans-common.c,v
retrieving revision 1.28
diff -c -p -r1.28 trans-common.c
*** fortran/trans-common.c	25 Jun 2005 00:40:36 -0000	1.28
--- fortran/trans-common.c	9 Jul 2005 15:25:09 -0000
*************** create_common (gfc_common_head *com, seg
*** 422,431 ****
  
    if (is_init)
      {
!       tree list, ctor, tmp;
        HOST_WIDE_INT offset = 0;
  
-       list = NULL_TREE;
        for (s = head; s; s = s->next)
          {
            if (s->sym->value)
--- 422,431 ----
  
    if (is_init)
      {
!       tree ctor, tmp;
        HOST_WIDE_INT offset = 0;
+       VEC(constructor_elt,gc) *v = NULL;
  
        for (s = head; s; s = s->next)
          {
            if (s->sym->value)
*************** create_common (gfc_common_head *com, seg
*** 442,461 ****
  	      tmp = gfc_conv_initializer (s->sym->value, &s->sym->ts,
  		  TREE_TYPE (s->field), s->sym->attr.dimension,
  		  s->sym->attr.pointer || s->sym->attr.allocatable);
! 	      list = tree_cons (s->field, tmp, list);
                offset = s->offset + s->length;
              }
          }
!       gcc_assert (list);
!       ctor = build1 (CONSTRUCTOR, union_type, nreverse(list));
        TREE_CONSTANT (ctor) = 1;
        TREE_INVARIANT (ctor) = 1;
        TREE_STATIC (ctor) = 1;
        DECL_INITIAL (decl) = ctor;
  
  #ifdef ENABLE_CHECKING
!       for (tmp = CONSTRUCTOR_ELTS (ctor); tmp; tmp = TREE_CHAIN (tmp))
! 	gcc_assert (TREE_CODE (TREE_PURPOSE (tmp)) == FIELD_DECL);
  #endif
      }
  
--- 442,466 ----
  	      tmp = gfc_conv_initializer (s->sym->value, &s->sym->ts,
  		  TREE_TYPE (s->field), s->sym->attr.dimension,
  		  s->sym->attr.pointer || s->sym->attr.allocatable);
! 
! 	      CONSTRUCTOR_APPEND_ELT (v, s->field, tmp);
                offset = s->offset + s->length;
              }
          }
!       gcc_assert (!VEC_empty (constructor_elt, v));
!       ctor = build_constructor (union_type, v);
        TREE_CONSTANT (ctor) = 1;
        TREE_INVARIANT (ctor) = 1;
        TREE_STATIC (ctor) = 1;
        DECL_INITIAL (decl) = ctor;
  
  #ifdef ENABLE_CHECKING
!       {
! 	tree field, value;
! 	unsigned HOST_WIDE_INT idx;
! 	FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), idx, field, value)
! 	  gcc_assert (TREE_CODE (field) == FIELD_DECL);
!       }
  #endif
      }
  
Index: fortran/trans-expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fortran/trans-expr.c,v
retrieving revision 1.53
diff -c -p -r1.53 trans-expr.c
*** fortran/trans-expr.c	25 Jun 2005 00:40:36 -0000	1.53
--- fortran/trans-expr.c	9 Jul 2005 15:25:10 -0000
*************** gfc_conv_structure (gfc_se * se, gfc_exp
*** 1812,1822 ****
  {
    gfc_constructor *c;
    gfc_component *cm;
-   tree head;
-   tree tail;
    tree val;
    tree type;
    tree tmp;
  
    gcc_assert (se->ss == NULL);
    gcc_assert (expr->expr_type == EXPR_STRUCTURE);
--- 1812,1821 ----
  {
    gfc_constructor *c;
    gfc_component *cm;
    tree val;
    tree type;
    tree tmp;
+   VEC(constructor_elt,gc) *v = NULL;
  
    gcc_assert (se->ss == NULL);
    gcc_assert (expr->expr_type == EXPR_STRUCTURE);
*************** gfc_conv_structure (gfc_se * se, gfc_exp
*** 1831,1839 ****
        return;
      }
  
-   head = build1 (CONSTRUCTOR, type, NULL_TREE);
-   tail = NULL_TREE;
- 
    cm = expr->ts.derived->components;
    for (c = expr->value.constructor; c; c = c->next, cm = cm->next)
      {
--- 1830,1835 ----
*************** gfc_conv_structure (gfc_se * se, gfc_exp
*** 1844,1862 ****
        val = gfc_conv_initializer (c->expr, &cm->ts,
  	  TREE_TYPE (cm->backend_decl), cm->dimension, cm->pointer);
  
!       /* Build a TREE_CHAIN to hold it.  */
!       val = tree_cons (cm->backend_decl, val, NULL_TREE);
! 
!       /* Add it to the list.  */
!       if (tail == NULL_TREE)
!         TREE_OPERAND(head, 0) = tail = val;
!       else
!         {
!           TREE_CHAIN (tail) = val;
!           tail = val;
!         }
      }
!   se->expr = head;
  }
  
  
--- 1840,1849 ----
        val = gfc_conv_initializer (c->expr, &cm->ts,
  	  TREE_TYPE (cm->backend_decl), cm->dimension, cm->pointer);
  
!       /* Append it to the constructor list.  */
!       CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
      }
!   se->expr = build_constructor (type, v);
  }
  
  
Index: fortran/trans-stmt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fortran/trans-stmt.c,v
retrieving revision 1.37
diff -c -p -r1.37 trans-stmt.c
*** fortran/trans-stmt.c	26 Jun 2005 05:21:25 -0000	1.37
--- fortran/trans-stmt.c	9 Jul 2005 15:25:11 -0000
*************** gfc_trans_character_select (gfc_code *co
*** 1220,1233 ****
        tmp = gfc_build_addr_expr (pvoid_type_node, labels[i]);
        node = tree_cons (ss_target, tmp, node);
  
!       tmp = build1 (CONSTRUCTOR, select_struct, nreverse (node));
        init = tree_cons (NULL_TREE, tmp, init);
      }
  
    type = build_array_type (select_struct, build_index_type
  			   (build_int_cst (NULL_TREE, n - 1)));
  
!   init = build1 (CONSTRUCTOR, type, nreverse(init));
    TREE_CONSTANT (init) = 1;
    TREE_INVARIANT (init) = 1;
    TREE_STATIC (init) = 1;
--- 1220,1233 ----
        tmp = gfc_build_addr_expr (pvoid_type_node, labels[i]);
        node = tree_cons (ss_target, tmp, node);
  
!       tmp = build_constructor_from_list (select_struct, nreverse (node));
        init = tree_cons (NULL_TREE, tmp, init);
      }
  
    type = build_array_type (select_struct, build_index_type
  			   (build_int_cst (NULL_TREE, n - 1)));
  
!   init = build_constructor_from_list (type, nreverse(init));
    TREE_CONSTANT (init) = 1;
    TREE_INVARIANT (init) = 1;
    TREE_STATIC (init) = 1;
Index: java/check-init.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/check-init.c,v
retrieving revision 1.65
diff -c -p -r1.65 check-init.c
*** java/check-init.c	25 Jun 2005 00:32:58 -0000	1.65
--- java/check-init.c	9 Jul 2005 15:25:11 -0000
*************** check_init (tree exp, words before)
*** 918,926 ****
  
      case NEW_ARRAY_INIT:
        {
! 	tree x = CONSTRUCTOR_ELTS (TREE_OPERAND (exp, 0));
! 	for ( ;  x != NULL_TREE;  x = TREE_CHAIN (x))
! 	  check_init (TREE_VALUE (x), before);
        }
        break;
  
--- 918,928 ----
  
      case NEW_ARRAY_INIT:
        {
! 	tree value;
! 	unsigned HOST_WIDE_INT idx;
! 	FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (TREE_OPERAND (exp, 0)),
! 				    idx, value)
! 	  check_init (value, before);
        }
        break;
  
Index: java/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/class.c,v
retrieving revision 1.235
diff -c -p -r1.235 class.c
*** java/class.c	2 Jul 2005 10:55:06 -0000	1.235
--- java/class.c	9 Jul 2005 15:25:12 -0000
*************** make_field_value (tree fdecl)
*** 1278,1284 ****
  
    PUSH_FIELD_VALUE
      (finit, "info",
!      build_constructor (field_info_union_node,
  	    build_tree_list
  	    ((FIELD_STATIC (fdecl)
  	      ? TREE_CHAIN (TYPE_FIELDS (field_info_union_node))
--- 1278,1284 ----
  
    PUSH_FIELD_VALUE
      (finit, "info",
!      build_constructor_from_list (field_info_union_node,
  	    build_tree_list
  	    ((FIELD_STATIC (fdecl)
  	      ? TREE_CHAIN (TYPE_FIELDS (field_info_union_node))
*************** make_method_value (tree mdecl)
*** 1359,1365 ****
  	    table = tree_cons (NULL_TREE, utf8, table);
  	  }
  	type = build_prim_array_type (ptr_type_node, length);
! 	table = build_constructor (type, table);
  	/* Compute something unique enough.  */
  	sprintf (buf, "_methods%d", method_name_count++);
  	array = build_decl (VAR_DECL, get_identifier (buf), type);
--- 1359,1365 ----
  	    table = tree_cons (NULL_TREE, utf8, table);
  	  }
  	type = build_prim_array_type (ptr_type_node, length);
! 	table = build_constructor_from_list (type, table);
  	/* Compute something unique enough.  */
  	sprintf (buf, "_methods%d", method_name_count++);
  	array = build_decl (VAR_DECL, get_identifier (buf), type);
*************** get_dispatch_table (tree type, tree this
*** 1480,1487 ****
    if (TARGET_VTABLE_USES_DESCRIPTORS)
      arraysize *= TARGET_VTABLE_USES_DESCRIPTORS;
    arraysize += 2;
!   return build_constructor (build_prim_array_type (nativecode_ptr_type_node,
! 						   arraysize), list);
  }
  
  
--- 1480,1488 ----
    if (TARGET_VTABLE_USES_DESCRIPTORS)
      arraysize *= TARGET_VTABLE_USES_DESCRIPTORS;
    arraysize += 2;
!   return build_constructor_from_list
! 	  (build_prim_array_type (nativecode_ptr_type_node,
! 				  arraysize), list);
  }
  
  
*************** make_class_data (tree type)
*** 1608,1615 ****
        field_array_type = build_prim_array_type (field_type_node, field_count);
        fields_decl = build_decl (VAR_DECL, mangled_classname ("_FL_", type),
  				field_array_type);
!       DECL_INITIAL (fields_decl) = build_constructor (field_array_type,
! 						      static_fields);
        TREE_STATIC (fields_decl) = 1;
        DECL_ARTIFICIAL (fields_decl) = 1;
        DECL_IGNORED_P (fields_decl) = 1;
--- 1609,1616 ----
        field_array_type = build_prim_array_type (field_type_node, field_count);
        fields_decl = build_decl (VAR_DECL, mangled_classname ("_FL_", type),
  				field_array_type);
!       DECL_INITIAL (fields_decl) = build_constructor_from_list
! 				    (field_array_type, static_fields);
        TREE_STATIC (fields_decl) = 1;
        DECL_ARTIFICIAL (fields_decl) = 1;
        DECL_IGNORED_P (fields_decl) = 1;
*************** make_class_data (tree type)
*** 1639,1646 ****
    method_array_type = build_prim_array_type (method_type_node, method_count);
    methods_decl = build_decl (VAR_DECL, mangled_classname ("_MT_", type),
  			     method_array_type);
!   DECL_INITIAL (methods_decl) = build_constructor (method_array_type,
! 						   nreverse (methods));
    TREE_STATIC (methods_decl) = 1;
    DECL_ARTIFICIAL (methods_decl) = 1;
    DECL_IGNORED_P (methods_decl) = 1;
--- 1640,1647 ----
    method_array_type = build_prim_array_type (method_type_node, method_count);
    methods_decl = build_decl (VAR_DECL, mangled_classname ("_MT_", type),
  			     method_array_type);
!   DECL_INITIAL (methods_decl) = build_constructor_from_list (method_array_type,
! 							     nreverse (methods));
    TREE_STATIC (methods_decl) = 1;
    DECL_ARTIFICIAL (methods_decl) = 1;
    DECL_IGNORED_P (methods_decl) = 1;
*************** make_class_data (tree type)
*** 1715,1721 ****
  	    }
  	  init = tree_cons (NULL_TREE, index, init); 
  	}
!       DECL_INITIAL (idecl) = build_constructor (interface_array_type, init);
        TREE_STATIC (idecl) = 1;
        DECL_ARTIFICIAL (idecl) = 1;
        DECL_IGNORED_P (idecl) = 1;
--- 1716,1723 ----
  	    }
  	  init = tree_cons (NULL_TREE, index, init); 
  	}
!       DECL_INITIAL (idecl) = build_constructor_from_list (interface_array_type,
! 							  init);
        TREE_STATIC (idecl) = 1;
        DECL_ARTIFICIAL (idecl) = 1;
        DECL_IGNORED_P (idecl) = 1;
*************** emit_symbol_table (tree name, tree the_t
*** 2528,2534 ****
  
    /* Put the list in the right order and make it a constructor. */
    list = nreverse (list);
!   table = build_constructor (symbols_array_type, list);  
  
    /* Make it the initial value for otable_syms and emit the decl. */
    DECL_INITIAL (the_syms_decl) = table;
--- 2530,2536 ----
  
    /* Put the list in the right order and make it a constructor. */
    list = nreverse (list);
!   table = build_constructor_from_list (symbols_array_type, list);  
  
    /* Make it the initial value for otable_syms and emit the decl. */
    DECL_INITIAL (the_syms_decl) = table;
*************** emit_catch_table (tree this_class)
*** 2589,2595 ****
    table = 
      build_decl (VAR_DECL, DECL_NAME (TYPE_CTABLE_DECL (this_class)), array_type);
    DECL_INITIAL (table) = 
!     build_constructor (array_type, TYPE_CATCH_CLASSES (this_class));
    TREE_STATIC (table) = 1;
    TREE_READONLY (table) = 1;  
    DECL_IGNORED_P (table) = 1;
--- 2591,2597 ----
    table = 
      build_decl (VAR_DECL, DECL_NAME (TYPE_CTABLE_DECL (this_class)), array_type);
    DECL_INITIAL (table) = 
!     build_constructor_from_list (array_type, TYPE_CATCH_CLASSES (this_class));
    TREE_STATIC (table) = 1;
    TREE_READONLY (table) = 1;  
    DECL_IGNORED_P (table) = 1;
*************** emit_assertion_table (tree class)
*** 2669,2675 ****
    
    /* Put the list in the right order and make it a constructor. */
    list = nreverse (list);
!   ctor = build_constructor (assertion_table_type, list);
  
    table_decl = build_decl (VAR_DECL, mangled_classname ("_type_assert_", class),
  			   assertion_table_type);
--- 2671,2677 ----
    
    /* Put the list in the right order and make it a constructor. */
    list = nreverse (list);
!   ctor = build_constructor_from_list (assertion_table_type, list);
  
    table_decl = build_decl (VAR_DECL, mangled_classname ("_type_assert_", class),
  			   assertion_table_type);
Index: java/constants.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/constants.c,v
retrieving revision 1.44
diff -c -p -r1.44 constants.c
*** java/constants.c	25 Jun 2005 00:32:58 -0000	1.44
--- java/constants.c	9 Jul 2005 15:25:12 -0000
*************** build_constants_constructor (void)
*** 515,522 ****
    
        data_decl = build_constant_data_ref ();
        TREE_TYPE (data_decl) = build_array_type (ptr_type_node, index_type);
!       DECL_INITIAL (data_decl) = build_constructor (TREE_TYPE (data_decl),
! 						    data_list);
        DECL_SIZE (data_decl) = TYPE_SIZE (TREE_TYPE (data_decl));
        DECL_SIZE_UNIT (data_decl) = TYPE_SIZE_UNIT (TREE_TYPE (data_decl));
        rest_of_decl_compilation (data_decl, 1, 0);
--- 515,522 ----
    
        data_decl = build_constant_data_ref ();
        TREE_TYPE (data_decl) = build_array_type (ptr_type_node, index_type);
!       DECL_INITIAL (data_decl) = build_constructor_from_list
! 				  (TREE_TYPE (data_decl), data_list);
        DECL_SIZE (data_decl) = TYPE_SIZE (TREE_TYPE (data_decl));
        DECL_SIZE_UNIT (data_decl) = TYPE_SIZE_UNIT (TREE_TYPE (data_decl));
        rest_of_decl_compilation (data_decl, 1, 0);
*************** build_constants_constructor (void)
*** 527,533 ****
  							   current_class),
  			      tags_type);
        TREE_STATIC (tags_decl) = 1;
!       DECL_INITIAL (tags_decl) = build_constructor (tags_type, tags_list);
        rest_of_decl_compilation (tags_decl, 1, 0);
        tags_value = build_address_of (tags_decl);
      }
--- 527,534 ----
  							   current_class),
  			      tags_type);
        TREE_STATIC (tags_decl) = 1;
!       DECL_INITIAL (tags_decl) = build_constructor_from_list
! 				 (tags_type, tags_list);
        rest_of_decl_compilation (tags_decl, 1, 0);
        tags_value = build_address_of (tags_decl);
      }
Index: java/java-gimplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/java-gimplify.c,v
retrieving revision 1.19
diff -c -p -r1.19 java-gimplify.c
*** java/java-gimplify.c	25 Jun 2005 00:33:01 -0000	1.19
--- java/java-gimplify.c	9 Jul 2005 15:25:12 -0000
*************** java_gimplify_new_array_init (tree exp)
*** 296,302 ****
    HOST_WIDE_INT ilength = java_array_type_length (array_type);
    tree length = build_int_cst (NULL_TREE, ilength);
    tree init = TREE_OPERAND (exp, 0);
!   tree values = CONSTRUCTOR_ELTS (init);
  
    tree array_ptr_type = build_pointer_type (array_type);
    tree tmp = create_tmp_var (array_ptr_type, "array");
--- 296,303 ----
    HOST_WIDE_INT ilength = java_array_type_length (array_type);
    tree length = build_int_cst (NULL_TREE, ilength);
    tree init = TREE_OPERAND (exp, 0);
!   tree value;
!   unsigned HOST_WIDE_INT cnt;
  
    tree array_ptr_type = build_pointer_type (array_type);
    tree tmp = create_tmp_var (array_ptr_type, "array");
*************** java_gimplify_new_array_init (tree exp)
*** 306,312 ****
    int index = 0;
  
    /* FIXME: try to allocate array statically?  */
!   while (values != NULL_TREE)
      {
        /* FIXME: Should use build_java_arrayaccess here, but avoid
  	 bounds checking.  */
--- 307,313 ----
    int index = 0;
  
    /* FIXME: try to allocate array statically?  */
!   FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (init), cnt, value)
      {
        /* FIXME: Should use build_java_arrayaccess here, but avoid
  	 bounds checking.  */
*************** java_gimplify_new_array_init (tree exp)
*** 317,325 ****
  				build4 (ARRAY_REF, element_type, lhs,
  					build_int_cst (NULL_TREE, index++),
  					NULL_TREE, NULL_TREE),
! 				TREE_VALUE (values));
        body = build2 (COMPOUND_EXPR, element_type, body, assignment);
-       values = TREE_CHAIN (values);
      }
  
    return build2 (COMPOUND_EXPR, array_ptr_type, body, tmp);
--- 318,325 ----
  				build4 (ARRAY_REF, element_type, lhs,
  					build_int_cst (NULL_TREE, index++),
  					NULL_TREE, NULL_TREE),
! 				value);
        body = build2 (COMPOUND_EXPR, element_type, body, assignment);
      }
  
    return build2 (COMPOUND_EXPR, array_ptr_type, body, tmp);
Index: java/java-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/java-tree.h,v
retrieving revision 1.239
diff -c -p -r1.239 java-tree.h
*** java/java-tree.h	8 Jul 2005 23:37:09 -0000	1.239
--- java/java-tree.h	9 Jul 2005 15:25:13 -0000
*************** extern tree *type_map;
*** 1763,1802 ****
  
  /* Start building a RECORD_TYPE constructor with a given TYPE in CONS. */
  #define START_RECORD_CONSTRUCTOR(CONS, CTYPE)	\
! { CONS = build_constructor ((CTYPE), NULL_TREE);	\
!   TREE_CHAIN (CONS) = TYPE_FIELDS (CTYPE); }
  
  /* Append a field initializer to CONS for the dummy field for the inherited
     fields.  The dummy field has the given VALUE, and the same type as the
     super-class.   Must be specified before calls to PUSH_FIELD_VALUE. */
! #define PUSH_SUPER_VALUE(CONS, VALUE)			\
! {							\
!   tree _field = TREE_CHAIN (CONS);			\
!   if (DECL_NAME (_field) != NULL_TREE)			\
!     abort ();						\
!   CONSTRUCTOR_ELTS (CONS)				\
!     = tree_cons (_field, (VALUE), CONSTRUCTOR_ELTS (CONS)); \
!   TREE_CHAIN (CONS) = TREE_CHAIN (_field);		\
! }
  
  /* Append a field initializer to CONS for a field with the given VALUE.
     NAME is a char* string used for error checking;
     the initializer must be specified in order. */
  #define PUSH_FIELD_VALUE(CONS, NAME, VALUE) 				\
! do									\
! {									\
!   tree _field = TREE_CHAIN (CONS);					\
!   if (strcmp (IDENTIFIER_POINTER (DECL_NAME (_field)), NAME) != 0) 	\
!     abort ();								\
!   CONSTRUCTOR_ELTS (CONS)						\
!     = tree_cons (_field, (VALUE), CONSTRUCTOR_ELTS (CONS));		\
!   TREE_CHAIN (CONS) = TREE_CHAIN (_field); 				\
! }									\
! while (0)
  
  /* Finish creating a record CONSTRUCTOR CONS. */
  #define FINISH_RECORD_CONSTRUCTOR(CONS) \
!   CONSTRUCTOR_ELTS(CONS) = nreverse (CONSTRUCTOR_ELTS (CONS))
  
  /* Macros on constructors invocations.  */
  #define CALL_CONSTRUCTOR_P(NODE)		\
--- 1763,1804 ----
  
  /* Start building a RECORD_TYPE constructor with a given TYPE in CONS. */
  #define START_RECORD_CONSTRUCTOR(CONS, CTYPE)	\
!   do { \
!     CONS = build_constructor ((CTYPE), VEC_alloc (constructor_elt, gc, 0)); \
!     CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (CONS), TYPE_FIELDS (CTYPE), \
! 			    NULL); \
!   } while (0)
  
  /* Append a field initializer to CONS for the dummy field for the inherited
     fields.  The dummy field has the given VALUE, and the same type as the
     super-class.   Must be specified before calls to PUSH_FIELD_VALUE. */
! #define PUSH_SUPER_VALUE(CONS, VALUE) \
!   do { \
!     constructor_elt *_elt___ = VEC_last (constructor_elt, \
! 				       CONSTRUCTOR_ELTS (CONS)); \
!     tree _next___ = TREE_CHAIN (_elt___->index); \
!     gcc_assert (!DECL_NAME (_elt___->index)); \
!     _elt___->value = VALUE; \
!     CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (CONS), _next___, NULL); \
!   } while (0)
  
  /* Append a field initializer to CONS for a field with the given VALUE.
     NAME is a char* string used for error checking;
     the initializer must be specified in order. */
  #define PUSH_FIELD_VALUE(CONS, NAME, VALUE) 				\
!   do { \
!     constructor_elt *_elt___ = VEC_last (constructor_elt, \
! 					 CONSTRUCTOR_ELTS (CONS)); \
!     tree _next___ = TREE_CHAIN (_elt___->index); \
!     gcc_assert (strcmp (IDENTIFIER_POINTER (DECL_NAME (_elt___->index)), \
! 			NAME) == 0); \
!     _elt___->value = VALUE; \
!     CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (CONS), _next___, NULL); \
!   } while (0)
  
  /* Finish creating a record CONSTRUCTOR CONS. */
  #define FINISH_RECORD_CONSTRUCTOR(CONS) \
!   VEC_pop (constructor_elt, CONSTRUCTOR_ELTS (CONS))
  
  /* Macros on constructors invocations.  */
  #define CALL_CONSTRUCTOR_P(NODE)		\
Index: java/jcf-write.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/jcf-write.c,v
retrieving revision 1.166
diff -c -p -r1.166 jcf-write.c
*** java/jcf-write.c	25 Jun 2005 00:33:03 -0000	1.166
--- java/jcf-write.c	9 Jul 2005 15:25:14 -0000
*************** generate_bytecode_insns (tree exp, int t
*** 2461,2474 ****
        break;
      case NEW_ARRAY_INIT:
        {
! 	tree values = CONSTRUCTOR_ELTS (TREE_OPERAND (exp, 0));
  	tree array_type = TREE_TYPE (TREE_TYPE (exp));
  	tree element_type = TYPE_ARRAY_ELEMENT (array_type);
  	HOST_WIDE_INT length = java_array_type_length (array_type);
  	if (target == IGNORE_TARGET)
  	  {
! 	    for ( ;  values != NULL_TREE;  values = TREE_CHAIN (values))
! 	      generate_bytecode_insns (TREE_VALUE (values), target, state);
  	    break;
  	  }
  	push_int_const (length, state);
--- 2461,2476 ----
        break;
      case NEW_ARRAY_INIT:
        {
! 	VEC(constructor_elt,gc) *v = CONSTRUCTOR_ELTS (TREE_OPERAND (exp, 0));
  	tree array_type = TREE_TYPE (TREE_TYPE (exp));
  	tree element_type = TYPE_ARRAY_ELEMENT (array_type);
+ 	unsigned HOST_WIDE_INT idx;
+ 	tree value;
  	HOST_WIDE_INT length = java_array_type_length (array_type);
  	if (target == IGNORE_TARGET)
  	  {
! 	    FOR_EACH_CONSTRUCTOR_VALUE (v, idx, value)
! 	      generate_bytecode_insns (value, target, state);
  	    break;
  	  }
  	push_int_const (length, state);
*************** generate_bytecode_insns (tree exp, int t
*** 2489,2504 ****
  	  }
  	offset = 0;
  	jopcode = OPCODE_iastore + adjust_typed_op (element_type, 7);
! 	for ( ;  values != NULL_TREE;  values = TREE_CHAIN (values), offset++)
  	  {
  	    int save_SP = state->code_SP;
  	    emit_dup (1, 0, state);
  	    push_int_const (offset, state);
  	    NOTE_PUSH (1);
! 	    generate_bytecode_insns (TREE_VALUE (values), STACK_TARGET, state);
  	    RESERVE (1);
  	    OP1 (jopcode);
  	    state->code_SP = save_SP;
  	  }
        }
        break;
--- 2491,2507 ----
  	  }
  	offset = 0;
  	jopcode = OPCODE_iastore + adjust_typed_op (element_type, 7);
! 	FOR_EACH_CONSTRUCTOR_VALUE (v, idx, value)
  	  {
  	    int save_SP = state->code_SP;
  	    emit_dup (1, 0, state);
  	    push_int_const (offset, state);
  	    NOTE_PUSH (1);
! 	    generate_bytecode_insns (value, STACK_TARGET, state);
  	    RESERVE (1);
  	    OP1 (jopcode);
  	    state->code_SP = save_SP;
+ 	    offset++;
  	  }
        }
        break;
Index: java/parse.y
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/parse.y,v
retrieving revision 1.548
diff -c -p -r1.548 parse.y
*** java/parse.y	7 Jul 2005 14:43:59 -0000	1.548
--- java/parse.y	9 Jul 2005 15:25:19 -0000
*************** static void missing_return_error (tree);
*** 274,280 ****
  static tree build_new_array_init (int, tree);
  static tree patch_new_array_init (tree, tree);
  static tree maybe_build_array_element_wfl (tree);
! static int array_constructor_check_entry (tree, tree);
  static const char *purify_type_name (const char *);
  static tree fold_constant_for_init (tree, tree);
  static jdeplist *reverse_jdep_list (struct parser_ctxt *);
--- 274,280 ----
  static tree build_new_array_init (int, tree);
  static tree patch_new_array_init (tree, tree);
  static tree maybe_build_array_element_wfl (tree);
! static int array_constructor_check_entry (tree, constructor_elt *);
  static const char *purify_type_name (const char *);
  static tree fold_constant_for_init (tree, tree);
  static jdeplist *reverse_jdep_list (struct parser_ctxt *);
*************** maybe_build_array_element_wfl (tree node
*** 14793,14799 ****
  static tree
  build_new_array_init (int location, tree values)
  {
!   tree constructor = build_constructor (NULL_TREE, values);
    tree to_return = build1 (NEW_ARRAY_INIT, NULL_TREE, constructor);
    EXPR_WFL_LINECOL (to_return) = location;
    return to_return;
--- 14793,14800 ----
  static tree
  build_new_array_init (int location, tree values)
  {
!   tree constructor = build_constructor_from_list (NULL_TREE,
! 						  nreverse (values));
    tree to_return = build1 (NEW_ARRAY_INIT, NULL_TREE, constructor);
    EXPR_WFL_LINECOL (to_return) = location;
    return to_return;
*************** static tree
*** 14807,14814 ****
  patch_new_array_init (tree type, tree node)
  {
    int error_seen = 0;
!   tree current, element_type;
!   HOST_WIDE_INT length;
    int all_constant = 1;
    tree init = TREE_OPERAND (node, 0);
  
--- 14808,14816 ----
  patch_new_array_init (tree type, tree node)
  {
    int error_seen = 0;
!   tree element_type;
!   unsigned HOST_WIDE_INT length;
!   constructor_elt *current;
    int all_constant = 1;
    tree init = TREE_OPERAND (node, 0);
  
*************** patch_new_array_init (tree type, tree no
*** 14822,14837 ****
    type = TREE_TYPE (type);
    element_type = TYPE_ARRAY_ELEMENT (type);
  
!   CONSTRUCTOR_ELTS (init) = nreverse (CONSTRUCTOR_ELTS (init));
! 
!   for (length = 0, current = CONSTRUCTOR_ELTS (init);
!        current;  length++, current = TREE_CHAIN (current))
      {
!       tree elt = TREE_VALUE (current);
        if (elt == NULL_TREE || TREE_CODE (elt) != NEW_ARRAY_INIT)
  	{
  	  error_seen |= array_constructor_check_entry (element_type, current);
! 	  elt = TREE_VALUE (current);
  	  /* When compiling to native code, STRING_CST is converted to
  	     INDIRECT_REF, but still with a TREE_CONSTANT flag. */
  	  if (! TREE_CONSTANT (elt) || TREE_CODE (elt) == INDIRECT_REF)
--- 14824,14839 ----
    type = TREE_TYPE (type);
    element_type = TYPE_ARRAY_ELEMENT (type);
  
!   for (length = 0;
!        VEC_iterate (constructor_elt, CONSTRUCTOR_ELTS (init),
! 		    length, current);
!        length++)
      {
!       tree elt = current->value;
        if (elt == NULL_TREE || TREE_CODE (elt) != NEW_ARRAY_INIT)
  	{
  	  error_seen |= array_constructor_check_entry (element_type, current);
! 	  elt = current->value;
  	  /* When compiling to native code, STRING_CST is converted to
  	     INDIRECT_REF, but still with a TREE_CONSTANT flag. */
  	  if (! TREE_CONSTANT (elt) || TREE_CODE (elt) == INDIRECT_REF)
*************** patch_new_array_init (tree type, tree no
*** 14839,14846 ****
  	}
        else
  	{
! 	  TREE_VALUE (current) = patch_new_array_init (element_type, elt);
! 	  TREE_PURPOSE (current) = NULL_TREE;
  	  all_constant = 0;
  	}
        if (elt && TREE_CODE (elt) == TREE_LIST
--- 14841,14848 ----
  	}
        else
  	{
! 	  current->value = patch_new_array_init (element_type, elt);
! 	  current->index = NULL_TREE;
  	  all_constant = 0;
  	}
        if (elt && TREE_CODE (elt) == TREE_LIST
*************** patch_new_array_init (tree type, tree no
*** 14869,14884 ****
     otherwise.  */
  
  static int
! array_constructor_check_entry (tree type, tree entry)
  {
    char *array_type_string = NULL;	/* For error reports */
    tree value, type_value, new_value, wfl_value, patched;
    int error_seen = 0;
  
    new_value = NULL_TREE;
!   wfl_value = TREE_VALUE (entry);
  
!   value = java_complete_tree (TREE_VALUE (entry));
    /* patch_string return error_mark_node if arg is error_mark_node */
    if ((patched = patch_string (value)))
      value = patched;
--- 14871,14886 ----
     otherwise.  */
  
  static int
! array_constructor_check_entry (tree type, constructor_elt *entry)
  {
    char *array_type_string = NULL;	/* For error reports */
    tree value, type_value, new_value, wfl_value, patched;
    int error_seen = 0;
  
    new_value = NULL_TREE;
!   wfl_value = entry->value;
  
!   value = java_complete_tree (entry->value);
    /* patch_string return error_mark_node if arg is error_mark_node */
    if ((patched = patch_string (value)))
      value = patched;
*************** array_constructor_check_entry (tree type
*** 14889,14895 ****
  
    /* At anytime, try_builtin_assignconv can report a warning on
       constant overflow during narrowing. */
!   SET_WFL_OPERATOR (wfl_operator, TREE_PURPOSE (entry), wfl_value);
    new_value = try_builtin_assignconv (wfl_operator, type, value);
    if (!new_value && (new_value = try_reference_assignconv (type, value)))
      type_value = promote_type (type);
--- 14891,14897 ----
  
    /* At anytime, try_builtin_assignconv can report a warning on
       constant overflow during narrowing. */
!   SET_WFL_OPERATOR (wfl_operator, entry->index, wfl_value);
    new_value = try_builtin_assignconv (wfl_operator, type, value);
    if (!new_value && (new_value = try_reference_assignconv (type, value)))
      type_value = promote_type (type);
*************** array_constructor_check_entry (tree type
*** 14908,14919 ****
      }
  
    if (new_value)
!     TREE_VALUE (entry) = new_value;
  
    if (array_type_string)
      free (array_type_string);
  
!   TREE_PURPOSE (entry) = NULL_TREE;
    return error_seen;
  }
  
--- 14910,14921 ----
      }
  
    if (new_value)
!     entry->value = new_value;
  
    if (array_type_string)
      free (array_type_string);
  
!   entry->index = NULL_TREE;
    return error_seen;
  }
  
Index: objc/objc-act.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/objc/objc-act.c,v
retrieving revision 1.287
diff -c -p -r1.287 objc-act.c
*** objc/objc-act.c	8 Jul 2005 23:37:10 -0000	1.287
--- objc/objc-act.c	9 Jul 2005 15:25:21 -0000
*************** objc_add_static_instance (tree construct
*** 2001,2007 ****
  static tree
  objc_build_constructor (tree type, tree elts)
  {
!   tree constructor = build_constructor (type, elts);
  
    TREE_CONSTANT (constructor) = 1;
    TREE_STATIC (constructor) = 1;
--- 2001,2007 ----
  static tree
  objc_build_constructor (tree type, tree elts)
  {
!   tree constructor = build_constructor_from_list (type, elts);
  
    TREE_CONSTANT (constructor) = 1;
    TREE_STATIC (constructor) = 1;
Index: testsuite/g++.dg/ext/complit3.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/ext/complit3.C,v
retrieving revision 1.2
diff -c -p -r1.2 complit3.C
*** testsuite/g++.dg/ext/complit3.C	22 Apr 2004 21:31:01 -0000	1.2
--- testsuite/g++.dg/ext/complit3.C	9 Jul 2005 15:25:22 -0000
***************
*** 2,8 ****
  
  int Compound_Literals_0()
  {
!   static int y[] = (int []) {1, 2, 3}; // { dg-error "" }
!   static int z[] = (int [3]) {1}; // { dg-error "" }
    return y[0]+z[0]; 
  }
--- 2,8 ----
  
  int Compound_Literals_0()
  {
!   static int y[] = (int []) {1, 2, 3}; // { dg-error "compound literal" }
!   static int z[] = (int [3]) {1}; // { dg-error "compound literal" }
    return y[0]+z[0]; 
  }
Index: testsuite/g++.dg/init/brace2.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/init/brace2.C,v
retrieving revision 1.1
diff -c -p -r1.1 brace2.C
*** testsuite/g++.dg/init/brace2.C	27 Nov 2002 01:59:43 -0000	1.1
--- testsuite/g++.dg/init/brace2.C	9 Jul 2005 15:25:22 -0000
***************
*** 3,8 ****
  int x = { 2 };
  const char * y = { "hello" };
  int a = 2;
! int b = { 2,3 }; // { dg-error "requires one element" }
  int c = { { 2 } } ; // { dg-error "braces around scalar initializer" }
  
--- 3,8 ----
  int x = { 2 };
  const char * y = { "hello" };
  int a = 2;
! int b = { 2,3 }; // { dg-error "too many initializers" }
  int c = { { 2 } } ; // { dg-error "braces around scalar initializer" }
  
Index: testsuite/g++.dg/warn/Wbraces2.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/warn/Wbraces2.C,v
retrieving revision 1.1
diff -c -p -r1.1 Wbraces2.C
*** testsuite/g++.dg/warn/Wbraces2.C	24 Feb 2005 21:21:28 -0000	1.1
--- testsuite/g++.dg/warn/Wbraces2.C	9 Jul 2005 15:25:23 -0000
***************
*** 2,15 ****
  // { dg-options "-Wmissing-braces" }
  int a[2][2] = { 0, 1, 2, 3 };			 // { dg-warning "missing braces" }
  int b[2][2] = { { 0, 1 }, { 2, 3 } };
! int c[2][2] = { { { 0 }, 1 }, { 2, 3 } };	 // { dg-error "brace-enclosed" }
  struct S { char s[6]; int i; };
  S d = { "hello", 1 };
  S e = { { "hello" }, 1 };
! S f = { { { "hello" } }, 1 };			 // { dg-error "brace-enclosed" }
  S g = { 'h', 'e', 'l', 'l', 'o', '\0', 1 };	 // { dg-warning "missing braces" }
  struct T { wchar_t s[6]; int i; };
  T i = { L"hello", 1 };
  T j = { { L"hello" }, 1 };
! T k = { { { L"hello" } }, 1 };			 // { dg-error "brace-enclosed" }
  T l = { L'h', L'e', L'l', L'l', L'o', L'\0', 1 };// { dg-warning "missing braces" }
--- 2,15 ----
  // { dg-options "-Wmissing-braces" }
  int a[2][2] = { 0, 1, 2, 3 };			 // { dg-warning "missing braces" }
  int b[2][2] = { { 0, 1 }, { 2, 3 } };
! int c[2][2] = { { { 0 }, 1 }, { 2, 3 } };	 // { dg-error "braces around scalar" }
  struct S { char s[6]; int i; };
  S d = { "hello", 1 };
  S e = { { "hello" }, 1 };
! S f = { { { "hello" } }, 1 };			 // { dg-error "braces around scalar" }
  S g = { 'h', 'e', 'l', 'l', 'o', '\0', 1 };	 // { dg-warning "missing braces" }
  struct T { wchar_t s[6]; int i; };
  T i = { L"hello", 1 };
  T j = { { L"hello" }, 1 };
! T k = { { { L"hello" } }, 1 };			 // { dg-error "braces around scalar" }
  T l = { L'h', L'e', L'l', L'l', L'o', L'\0', 1 };// { dg-warning "missing braces" }
