This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


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

C++ PATCH to initialization code


We weren't performing default-initialization in new-expressions, as in
g++.other/new6.C.  I also took the opportunity to simplify build_vec_init
a bit, though not as much as I might have liked.

2001-01-03  Jason Merrill  <jason@redhat.com>

	* init.c (build_default_init): New fn.
	(perform_member_init): Split out from here.
	(build_new_1): Use it.  Simplify initialization logic.
	(build_vec_init): Take an array, rather than a pointer and maxindex.
	Speed up simple initializations.  Don't clean up if we're assigning.
	* cp-tree.h: Adjust.
	* decl2.c (do_static_initialization): Remove TREE_VEC case.
	* parse.y (new_initializer): Return void_zero_node for ().
	* typeck.c (build_modify_expr): Handle getting a CONSTRUCTOR.
	* typeck2.c (digest_init): Only complain about user-written
	CONSTRUCTORs.

*** cp-tree.h.~1~	Tue Jan  2 20:15:36 2001
--- cp-tree.h	Tue Jan  2 20:15:37 2001
*************** extern tree build_member_call			PARAMS (
*** 4047,4053 ****
  extern tree build_offset_ref			PARAMS ((tree, tree));
  extern tree resolve_offset_ref			PARAMS ((tree));
  extern tree build_new				PARAMS ((tree, tree, tree, int));
! extern tree build_vec_init			PARAMS ((tree, tree, tree, tree, int));
  extern tree build_x_delete			PARAMS ((tree, int, tree));
  extern tree build_delete			PARAMS ((tree, tree, special_function_kind, int, int));
  extern tree build_vbase_delete			PARAMS ((tree, tree));
--- 4047,4053 ----
  extern tree build_offset_ref			PARAMS ((tree, tree));
  extern tree resolve_offset_ref			PARAMS ((tree));
  extern tree build_new				PARAMS ((tree, tree, tree, int));
! extern tree build_vec_init			PARAMS ((tree, tree, int));
  extern tree build_x_delete			PARAMS ((tree, int, tree));
  extern tree build_delete			PARAMS ((tree, tree, special_function_kind, int, int));
  extern tree build_vbase_delete			PARAMS ((tree, tree));
*** decl2.c.~1~	Tue Jan  2 20:15:36 2001
--- decl2.c	Wed Jan  3 02:28:28 2001
*************** do_static_initialization (decl, init)
*** 3383,3392 ****
    if (IS_AGGR_TYPE (TREE_TYPE (decl))
        || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
      expr = build_aggr_init (decl, init, 0);
-   else if (TREE_CODE (init) == TREE_VEC)
-     expr = build_vec_init (decl, TREE_VEC_ELT (init, 0),
- 			   TREE_VEC_ELT (init, 1),
- 			   TREE_VEC_ELT (init, 2), 0);
    else
      {
        expr = build (INIT_EXPR, TREE_TYPE (decl), decl, init);
--- 3383,3388 ----
*** init.c.~1~	Tue Jan  2 20:15:36 2001
--- init.c	Wed Jan  3 02:14:12 2001
*************** static tree initializing_context PARAMS 
*** 49,54 ****
--- 49,55 ----
  static void expand_cleanup_for_base PARAMS ((tree, tree));
  static tree get_temp_regvar PARAMS ((tree, tree));
  static tree dfs_initialize_vtbl_ptrs PARAMS ((tree, void *));
+ static tree build_default_init PARAMS ((tree));
  static tree build_new_1	PARAMS ((tree));
  static tree get_cookie_size PARAMS ((tree));
  static tree build_dtor_call PARAMS ((tree, special_function_kind, int));
*************** initialize_vtbl_ptrs (addr)
*** 193,198 ****
--- 194,243 ----
      fixup_all_virtual_upcast_offsets (addr);
  }
  
+ /* [dcl.init]:
+ 
+   To default-initialize an object of type T means:
+ 
+   --if T is a non-POD class type (clause _class_), the default construc-
+     tor  for  T is called (and the initialization is ill-formed if T has
+     no accessible default constructor);
+ 
+   --if T is an array type, each element is default-initialized;
+ 
+   --otherwise, the storage for the object is zero-initialized.
+ 
+   A program that calls for default-initialization of an entity of refer-
+   ence type is ill-formed.  */
+ 
+ static tree
+ build_default_init (type)
+      tree type;
+ {
+   tree init = NULL_TREE;
+ 
+   if (TYPE_NEEDS_CONSTRUCTING (type))
+     /* Other code will handle running the default constructor.  We can't do
+        anything with a CONSTRUCTOR for arrays here, as that would imply
+        copy-initialization.  */
+     return NULL_TREE;
+   else if (AGGREGATE_TYPE_P (type))
+     {
+       /* This is a default initialization of an aggregate, but not one of
+ 	 non-POD class type.  We cleverly notice that the initialization
+ 	 rules in such a case are the same as for initialization with an
+ 	 empty brace-initialization list.  */
+       init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, NULL_TREE);
+     }
+   else if (TREE_CODE (type) == REFERENCE_TYPE)
+     /*   --if T is a reference type, no initialization is performed.  */
+     return NULL_TREE;
+   else
+     init = integer_zero_node;
+ 
+   init = digest_init (type, init, 0);
+   return init;
+ }
+ 
  /* Subroutine of emit_base_init.  */
  
  static void
*************** perform_member_init (member, init, expli
*** 234,242 ****
  	  && TREE_CODE (TREE_TYPE (TREE_VALUE (init))) == ARRAY_TYPE)
  	{
  	  /* Initialization of one array from another.  */
! 	  finish_expr_stmt 
! 	    (build_vec_init (TREE_OPERAND (decl, 1), decl,
! 			     array_type_nelts (type), TREE_VALUE (init), 1));
  	}
        else
  	finish_expr_stmt (build_aggr_init (decl, init, 0));
--- 279,285 ----
  	  && TREE_CODE (TREE_TYPE (TREE_VALUE (init))) == ARRAY_TYPE)
  	{
  	  /* Initialization of one array from another.  */
! 	  finish_expr_stmt (build_vec_init (decl, TREE_VALUE (init), 1));
  	}
        else
  	finish_expr_stmt (build_aggr_init (decl, init, 0));
*************** perform_member_init (member, init, expli
*** 247,274 ****
  	{
  	  if (explicit)
  	    {
! 	      /* default-initialization.  */
! 	      if (AGGREGATE_TYPE_P (type))
! 		{
! 		  /* This is a default initialization of an aggregate,
! 		     but not one of non-POD class type.  We cleverly
! 		     notice that the initialization rules in such a
! 		     case are the same as for initialization with an
! 		     empty brace-initialization list.  We don't want
! 		     to call build_modify_expr as that will go looking
! 		     for constructors and such.  */
! 		  tree e = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE);
! 		  TREE_SIDE_EFFECTS (e) = 1;
! 		  finish_expr_stmt (build (INIT_EXPR, type, decl, e));
! 		}
!  	      else if (TREE_CODE (type) == REFERENCE_TYPE)
! 		cp_error ("default-initialization of `%#D', which has reference type",
! 			  member);
! 	      else
! 		init = integer_zero_node;
  	    }
  	  /* member traversal: note it leaves init NULL */
! 	  else if (TREE_CODE (TREE_TYPE (member)) == REFERENCE_TYPE)
  	    cp_pedwarn ("uninitialized reference member `%D'", member);
  	}
        else if (TREE_CODE (init) == TREE_LIST)
--- 290,303 ----
  	{
  	  if (explicit)
  	    {
! 	      init = build_default_init (type);
! 	      if (TREE_CODE (type) == REFERENCE_TYPE)
! 		cp_warning
! 		  ("default-initialization of `%#D', which has reference type",
! 		   member);
  	    }
  	  /* member traversal: note it leaves init NULL */
! 	  else if (TREE_CODE (type) == REFERENCE_TYPE)
  	    cp_pedwarn ("uninitialized reference member `%D'", member);
  	}
        else if (TREE_CODE (init) == TREE_LIST)
*************** build_aggr_init (exp, init, flags)
*** 1212,1218 ****
  	  if (init)
  	    TREE_TYPE (init) = TYPE_MAIN_VARIANT (itype);
  	}
!       stmt_expr = build_vec_init (exp, exp, array_type_nelts (type), init,
  				  init && same_type_p (TREE_TYPE (init),
  						       TREE_TYPE (exp)));
        TREE_READONLY (exp) = was_const;
--- 1241,1247 ----
  	  if (init)
  	    TREE_TYPE (init) = TYPE_MAIN_VARIANT (itype);
  	}
!       stmt_expr = build_vec_init (exp, init,
  				  init && same_type_p (TREE_TYPE (init),
  						       TREE_TYPE (exp)));
        TREE_READONLY (exp) = was_const;
*************** build_new_1 (exp)
*** 2237,2242 ****
--- 2266,2272 ----
  {
    tree placement, init;
    tree type, true_type, size, rval, t;
+   tree full_type;
    tree nelts = NULL_TREE;
    tree alloc_call, alloc_expr, alloc_node;
    tree cookie_expr, init_expr;
*************** build_new_1 (exp)
*** 2264,2270 ****
--- 2294,2307 ----
        has_array = 1;
        nelts = TREE_OPERAND (type, 1);
        type = TREE_OPERAND (type, 0);
+ 
+       full_type = cp_build_binary_op (MINUS_EXPR, nelts, integer_one_node);
+       full_type = build_index_type (full_type);
+       full_type = build_cplus_array_type (type, full_type);
      }
+   else
+     full_type = type;
+ 
    true_type = type;
  
    code = has_array ? VEC_NEW_EXPR : NEW_EXPR;
*************** build_new_1 (exp)
*** 2395,2401 ****
      /* Adjust so we're pointing to the start of the object.  */
      alloc_expr = build (PLUS_EXPR, TREE_TYPE (alloc_expr),
  			alloc_expr, cookie_size);
!   alloc_expr = convert (build_pointer_type (type), alloc_expr);
  
    /* Now save the allocation expression so we only evaluate it once.  */
    alloc_expr = get_target_expr (alloc_expr);
--- 2432,2441 ----
      /* Adjust so we're pointing to the start of the object.  */
      alloc_expr = build (PLUS_EXPR, TREE_TYPE (alloc_expr),
  			alloc_expr, cookie_size);
! 
!   /* While we're working, use a pointer to the type we've actually
!      allocated.  */
!   alloc_expr = convert (build_pointer_type (full_type), alloc_expr);
  
    /* Now save the allocation expression so we only evaluate it once.  */
    alloc_expr = get_target_expr (alloc_expr);
*************** build_new_1 (exp)
*** 2434,2499 ****
    init_expr = NULL_TREE;
    if (TYPE_NEEDS_CONSTRUCTING (type) || init)
      {
!       if (! TYPE_NEEDS_CONSTRUCTING (type)
! 	  && ! IS_AGGR_TYPE (type) && ! has_array)
  	{
  	  /* We are processing something like `new int (10)', which
  	     means allocate an int, and initialize it with 10.  */
- 	  tree deref;
- 	  tree deref_type;
- 
- 	  deref = build_indirect_ref (alloc_node, NULL_PTR);
  
! 	  /* Even for something like `new const int (10)' we must
! 	     allow the expression to be non-const while we do the
! 	     initialization.  */
! 	  deref_type = TREE_TYPE (deref);
! 	  if (CP_TYPE_CONST_P (deref_type))
! 	    TREE_TYPE (deref) 
! 	      = cp_build_qualified_type (deref_type,
! 					 CP_TYPE_QUALS (deref_type) 
! 					 & ~TYPE_QUAL_CONST);
! 	  TREE_READONLY (deref) = 0;
! 
! 	  if (TREE_CHAIN (init) != NULL_TREE)
! 	    pedwarn
! 	      ("initializer list being treated as compound expression");
! 	  else if (TREE_CODE (init) == CONSTRUCTOR)
  	    {
! 	      pedwarn
! 		("initializer list appears where operand should be used");
! 	      init = TREE_OPERAND (init, 1);
  	    }
- 	  init = build_compound_expr (init);
- 
- 	  init = convert_for_initialization (deref, type, init, LOOKUP_NORMAL,
- 					     "new", NULL_TREE, 0);
- 	  init_expr = build_modify_expr (deref, NOP_EXPR, init);
- 	}
-       else if (! has_array)
- 	{
- 	  /* Constructors are never virtual. If it has an initialization, we
- 	     need to complain if we aren't allowed to use the ctor that took
- 	     that argument.  */
- 	  int flags = LOOKUP_NORMAL|LOOKUP_NONVIRTUAL|LOOKUP_COMPLAIN;
- 
- 	  init_expr = build_indirect_ref (alloc_node, NULL_PTR);
- 
- 	  init_expr = build_method_call (init_expr, 
- 					 complete_ctor_identifier,
- 					 init, TYPE_BINFO (true_type), flags);
- 	}
-       else
- 	{
- 	  if (init && pedantic)
- 	    cp_pedwarn ("initialization in array new");
  
! 	  init_expr = convert (build_pointer_type (true_type), alloc_node);
! 	  init_expr = (build_vec_init
! 		       (NULL_TREE, init_expr,
! 			cp_build_binary_op (MINUS_EXPR, nelts,
! 					    integer_one_node),
! 			init, /*from_array=*/0));
  	}
  
        if (init_expr == error_mark_node)
--- 2474,2513 ----
    init_expr = NULL_TREE;
    if (TYPE_NEEDS_CONSTRUCTING (type) || init)
      {
!       init_expr = build_indirect_ref (alloc_node, NULL_PTR);
! 
!       if (init == void_zero_node)
! 	init = build_default_init (full_type);
!       else if (init && pedantic && has_array)
! 	cp_pedwarn ("ISO C++ forbids initialization in array new");
! 
!       if (has_array)
! 	init_expr = build_vec_init (init_expr, init, 0);
!       else if (TYPE_NEEDS_CONSTRUCTING (type))
! 	init_expr = build_method_call (init_expr, 
! 				       complete_ctor_identifier,
! 				       init, TYPE_BINFO (true_type),
! 				       LOOKUP_NORMAL);
!       else
  	{
  	  /* We are processing something like `new int (10)', which
  	     means allocate an int, and initialize it with 10.  */
  
! 	  if (TREE_CODE (init) == TREE_LIST)
  	    {
! 	      if (TREE_CHAIN (init) != NULL_TREE)
! 		pedwarn
! 		  ("initializer list being treated as compound expression");
! 	      init = build_compound_expr (init);
! 	    }
! 	  else if (TREE_CODE (init) == CONSTRUCTOR
! 		   && TREE_TYPE (init) == NULL_TREE)
! 	    {
! 	      pedwarn ("ISO C++ forbids aggregate initializer to new");
! 	      init = digest_init (type, init, 0);
  	    }
  
! 	  init_expr = build_modify_expr (init_expr, INIT_EXPR, init);
  	}
  
        if (init_expr == error_mark_node)
*************** build_new_1 (exp)
*** 2577,2592 ****
    if (rval == alloc_node)
      /* If we didn't modify anything, strip the TARGET_EXPR and return the
         (adjusted) call.  */
!     return TREE_OPERAND (alloc_expr, 1);
! 
!   if (check_new)
      {
!       tree ifexp = cp_build_binary_op (NE_EXPR, alloc_node,
! 				       integer_zero_node);
!       rval = build_conditional_expr (ifexp, rval, alloc_node);
      }
  
!   rval = build (COMPOUND_EXPR, TREE_TYPE (rval), alloc_expr, rval);
  
    return rval;
  }
--- 2591,2612 ----
    if (rval == alloc_node)
      /* If we didn't modify anything, strip the TARGET_EXPR and return the
         (adjusted) call.  */
!     rval = TREE_OPERAND (alloc_expr, 1);
!   else
      {
!       if (check_new)
! 	{
! 	  tree ifexp = cp_build_binary_op (NE_EXPR, alloc_node,
! 					   integer_zero_node);
! 	  rval = build_conditional_expr (ifexp, rval, alloc_node);
! 	}
! 
!       rval = build (COMPOUND_EXPR, TREE_TYPE (rval), alloc_expr, rval);
      }
  
!   /* Now strip the outer ARRAY_TYPE, so we return a pointer to the first
!      element.  */
!   rval = convert (build_pointer_type (type), rval);
  
    return rval;
  }
*************** get_temp_regvar (type, init)
*** 2767,2778 ****
  /* `build_vec_init' returns tree structure that performs
     initialization of a vector of aggregate types.
  
!    DECL is passed only for error reporting, and provides line number
!    and source file name information.
!    BASE is the space where the vector will be.  For a vector of Ts,
!      the type of BASE is `T*'.
!    MAXINDEX is the maximum index of the array (one less than the
! 	    number of elements).
     INIT is the (possibly NULL) initializer.
  
     FROM_ARRAY is 0 if we should init everything with INIT
--- 2787,2793 ----
  /* `build_vec_init' returns tree structure that performs
     initialization of a vector of aggregate types.
  
!    BASE is a reference to the vector, of ARRAY_TYPE.
     INIT is the (possibly NULL) initializer.
  
     FROM_ARRAY is 0 if we should init everything with INIT
*************** get_temp_regvar (type, init)
*** 2783,2790 ****
     but use assignment instead of initialization.  */
  
  tree
! build_vec_init (decl, base, maxindex, init, from_array)
!      tree decl, base, maxindex, init;
       int from_array;
  {
    tree rval;
--- 2798,2805 ----
     but use assignment instead of initialization.  */
  
  tree
! build_vec_init (base, init, from_array)
!      tree base, init;
       int from_array;
  {
    tree rval;
*************** build_vec_init (decl, base, maxindex, in
*** 2792,2799 ****
    tree size;
    tree itype = NULL_TREE;
    tree iterator;
    /* The type of an element in the array.  */
!   tree type;
    /* The type of a pointer to an element in the array.  */
    tree ptype;
    tree stmt_expr;
--- 2807,2816 ----
    tree size;
    tree itype = NULL_TREE;
    tree iterator;
+   /* The type of the array.  */
+   tree atype = TREE_TYPE (base);
    /* The type of an element in the array.  */
!   tree type = TREE_TYPE (atype);
    /* The type of a pointer to an element in the array.  */
    tree ptype;
    tree stmt_expr;
*************** build_vec_init (decl, base, maxindex, in
*** 2802,2839 ****
    tree try_block = NULL_TREE;
    tree try_body = NULL_TREE;
    int num_initialized_elts = 0;
  
-   maxindex = cp_convert (ptrdiff_type_node, maxindex);
    if (maxindex == error_mark_node)
      return error_mark_node;
  
!   type = TREE_TYPE (TREE_TYPE (base));
    ptype = build_pointer_type (type);
    size = size_in_bytes (type);
  
    /* The code we are generating looks like:
  
         T* t1 = (T*) base;
!        T* rval = base;
         ptrdiff_t iterator = maxindex;
         try {
!          ... initializations from CONSTRUCTOR ...
!          if (iterator != -1) {
! 	   do {
! 	     ... initialize *base ...
! 	     ++base;
! 	   } while (--iterator != -1);
! 	 }
         } catch (...) {
           ... destroy elements that were constructed ...
         }
         
       We can omit the try and catch blocks if we know that the
       initialization will never throw an exception, or if the array
!      elements do not have destructors.  If we have a CONSTRUCTOR to
!      give us initialization information, we emit code to initialize
!      each of the elements before the loop in the try block, and then
!      iterate over fewer elements.  We can omit the loop completely if
       the elements of the array do not have constructors.  
  
       We actually wrap the entire body of the above in a STMT_EXPR, for
--- 2819,2874 ----
    tree try_block = NULL_TREE;
    tree try_body = NULL_TREE;
    int num_initialized_elts = 0;
+   tree maxindex = array_type_nelts (TREE_TYPE (base));
  
    if (maxindex == error_mark_node)
      return error_mark_node;
  
!   /* For g++.ext/arrnew.C.  */
!   if (init && TREE_CODE (init) == CONSTRUCTOR && TREE_TYPE (init) == NULL_TREE)
!     init = digest_init (atype, init, 0);
!       
!   if (init && !TYPE_NEEDS_CONSTRUCTING (type)
!       && ((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 (target_type (type))))
! 	  || from_array))
!     {
!       /* Do non-default initialization of POD arrays resulting from
! 	 brace-enclosed initializers.  In this case, digest_init and
! 	 store_constructor will handle the semantics for us.  */
! 
!       stmt_expr = build (INIT_EXPR, atype, base, init);
!       TREE_SIDE_EFFECTS (stmt_expr) = 1;
!       return stmt_expr;
!     }
! 
!   maxindex = cp_convert (ptrdiff_type_node, maxindex);
    ptype = build_pointer_type (type);
    size = size_in_bytes (type);
+   if (TREE_CODE (TREE_TYPE (base)) == ARRAY_TYPE)
+     base = cp_convert (ptype, default_conversion (base));
  
    /* The code we are generating looks like:
  
         T* t1 = (T*) base;
!        T* rval = t1;
         ptrdiff_t iterator = maxindex;
         try {
! 	 do {
! 	   ... initialize *t1 ...
! 	   ++t1;
! 	 } while (--iterator != -1);
         } catch (...) {
           ... destroy elements that were constructed ...
         }
+        return rval;
         
       We can omit the try and catch blocks if we know that the
       initialization will never throw an exception, or if the array
!      elements do not have destructors.  We can omit the loop completely if
       the elements of the array do not have constructors.  
  
       We actually wrap the entire body of the above in a STMT_EXPR, for
*************** build_vec_init (decl, base, maxindex, in
*** 2848,2871 ****
    begin_init_stmts (&stmt_expr, &compound_stmt);
    destroy_temps = stmts_are_full_exprs_p ();
    current_stmt_tree ()->stmts_are_full_exprs_p = 0;
!   rval = get_temp_regvar (ptype, 
! 			  cp_convert (ptype, default_conversion (base)));
    base = get_temp_regvar (ptype, rval);
    iterator = get_temp_regvar (ptrdiff_type_node, maxindex);
  
    /* Protect the entire array initialization so that we can destroy
!      the partially constructed array if an exception is thrown.  */
!   if (flag_exceptions && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
      {
        try_block = begin_try_block ();
        try_body = begin_compound_stmt (/*has_no_scope=*/1);
      }
  
!   if (init != NULL_TREE && TREE_CODE (init) == CONSTRUCTOR
!       && (!decl || same_type_p (TREE_TYPE (init), TREE_TYPE (decl))))
      {
!       /* Do non-default initialization resulting from brace-enclosed
! 	 initializers.  */
  
        tree elts;
        from_array = 0;
--- 2883,2906 ----
    begin_init_stmts (&stmt_expr, &compound_stmt);
    destroy_temps = stmts_are_full_exprs_p ();
    current_stmt_tree ()->stmts_are_full_exprs_p = 0;
!   rval = get_temp_regvar (ptype, base);
    base = get_temp_regvar (ptype, rval);
    iterator = get_temp_regvar (ptrdiff_type_node, maxindex);
  
    /* Protect the entire array initialization so that we can destroy
!      the partially constructed array if an exception is thrown.
!      But don't do this if we're assigning.  */
!   if (flag_exceptions && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
!       && from_array != 2)
      {
        try_block = begin_try_block ();
        try_body = begin_compound_stmt (/*has_no_scope=*/1);
      }
  
!   if (init != NULL_TREE && TREE_CODE (init) == CONSTRUCTOR)
      {
!       /* Do non-default initialization of non-POD arrays resulting from
! 	 brace-enclosed initializers.  */
  
        tree elts;
        from_array = 0;
*************** build_vec_init (decl, base, maxindex, in
*** 2883,2898 ****
  	    finish_expr_stmt (build_modify_expr (baseref, NOP_EXPR,
  						 elt));
  
! 	  finish_expr_stmt (build_modify_expr 
! 			    (base, 
! 			     NOP_EXPR,
! 			     build (PLUS_EXPR, build_pointer_type (type),
! 				    base, size)));
! 	  finish_expr_stmt (build_modify_expr
! 			    (iterator,
! 			     NOP_EXPR,
! 			     build (MINUS_EXPR, ptrdiff_type_node,
! 				    iterator, integer_one_node)));
  	}
  
        /* Clear out INIT so that we don't get confused below.  */
--- 2918,2925 ----
  	    finish_expr_stmt (build_modify_expr (baseref, NOP_EXPR,
  						 elt));
  
! 	  finish_expr_stmt (build_unary_op (PREINCREMENT_EXPR, base, 0));
! 	  finish_expr_stmt (build_unary_op (PREDECREMENT_EXPR, iterator, 0));
  	}
  
        /* Clear out INIT so that we don't get confused below.  */
*************** build_vec_init (decl, base, maxindex, in
*** 2903,2913 ****
        /* If initializing one array from another, initialize element by
  	 element.  We rely upon the below calls the do argument
  	 checking.  */ 
-       if (decl == NULL_TREE)
- 	{
- 	  sorry ("initialization of array from dissimilar array type");
- 	  return error_mark_node;
- 	}
        if (init)
  	{
  	  base2 = default_conversion (init);
--- 2930,2935 ----
*************** build_vec_init (decl, base, maxindex, in
*** 2988,3007 ****
        else if (TREE_CODE (type) == ARRAY_TYPE)
  	{
  	  if (init != 0)
! 	    sorry ("cannot initialize multi-dimensional array with initializer");
! 	  elt_init = (build_vec_init 
! 		      (decl, 
! 		       build1 (NOP_EXPR, 
! 			       build_pointer_type (TREE_TYPE (type)),
! 			       base),
! 		       array_type_nelts (type), 0, 0));
  	}
        else
  	elt_init = build_aggr_init (build1 (INDIRECT_REF, type, base), 
  				    init, 0);
        
        /* The initialization of each array element is a
! 	 full-expression.  */
        if (!building_stmt_tree ())
  	{
  	  genrtl_expr_stmt (elt_init);
--- 3010,3026 ----
        else if (TREE_CODE (type) == ARRAY_TYPE)
  	{
  	  if (init != 0)
! 	    sorry
! 	      ("cannot initialize multi-dimensional array with initializer");
! 	  elt_init = build_vec_init (build1 (INDIRECT_REF, type, base),
! 				     0, 0);
  	}
        else
  	elt_init = build_aggr_init (build1 (INDIRECT_REF, type, base), 
  				    init, 0);
        
        /* The initialization of each array element is a
! 	 full-expression, as per core issue 124.  */
        if (!building_stmt_tree ())
  	{
  	  genrtl_expr_stmt (elt_init);
*************** build_vec_init (decl, base, maxindex, in
*** 3014,3038 ****
  	  current_stmt_tree ()->stmts_are_full_exprs_p = 0;
  	}
  
!       finish_expr_stmt (build_modify_expr
! 			(base,
! 			 NOP_EXPR,
! 			 build (PLUS_EXPR, build_pointer_type (type), 
! 				base, size)));
        if (base2)
! 	finish_expr_stmt (build_modify_expr
! 			  (base2,
! 			   NOP_EXPR,
! 			   build (PLUS_EXPR, build_pointer_type (type), 
! 				  base2, size)));
  
        finish_compound_stmt (/*has_no_scope=*/1, do_body);
        finish_do_body (do_stmt);
        finish_do_stmt (build (NE_EXPR, boolean_type_node,
! 			     build (PREDECREMENT_EXPR, 
! 				    ptrdiff_type_node, 
! 				    iterator,
! 				    integer_one_node), 
  			     minus_one_node),
  		      do_stmt);
  
--- 3033,3046 ----
  	  current_stmt_tree ()->stmts_are_full_exprs_p = 0;
  	}
  
!       finish_expr_stmt (build_unary_op (PREINCREMENT_EXPR, base, 0));
        if (base2)
! 	finish_expr_stmt (build_unary_op (PREINCREMENT_EXPR, base2, 0));
  
        finish_compound_stmt (/*has_no_scope=*/1, do_body);
        finish_do_body (do_stmt);
        finish_do_stmt (build (NE_EXPR, boolean_type_node,
! 			     build_unary_op (PREDECREMENT_EXPR, iterator, 0),
  			     minus_one_node),
  		      do_stmt);
  
*************** build_vec_init (decl, base, maxindex, in
*** 3041,3047 ****
      }
  
    /* Make sure to cleanup any partially constructed elements.  */
!   if (flag_exceptions && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
      {
        tree e;
  
--- 3049,3056 ----
      }
  
    /* Make sure to cleanup any partially constructed elements.  */
!   if (flag_exceptions && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
!       && from_array != 2)
      {
        tree e;
  
*** parse.y.~1~	Tue Jan  2 20:15:36 2001
--- parse.y	Tue Jan  2 20:15:37 2001
*************** new_initializer:
*** 1268,1274 ****
  	  '(' nonnull_exprlist ')'
  		{ $$ = $2; }
  	| LEFT_RIGHT
! 		{ $$ = NULL_TREE; }
  	| '(' typespec ')'
  		{
  		  cp_error ("`%T' is not a valid expression", $2.t);
--- 1268,1274 ----
  	  '(' nonnull_exprlist ')'
  		{ $$ = $2; }
  	| LEFT_RIGHT
! 		{ $$ = void_zero_node; }
  	| '(' typespec ')'
  		{
  		  cp_error ("`%T' is not a valid expression", $2.t);
*** typeck.c.~1~	Tue Jan  2 20:15:36 2001
--- typeck.c	Tue Jan  2 20:15:37 2001
*************** build_modify_expr (lhs, modifycode, rhs)
*** 5627,5633 ****
  
    if (modifycode == INIT_EXPR)
      {
!       if (! IS_AGGR_TYPE (lhstype))
  	/* Do the default thing */;
        else
  	{
--- 5627,5641 ----
  
    if (modifycode == INIT_EXPR)
      {
!       if (TREE_CODE (rhs) == CONSTRUCTOR)
! 	{
! 	  if (! same_type_p (TREE_TYPE (rhs), lhstype))
! 	    abort ();
! 	  result = build (INIT_EXPR, lhstype, lhs, rhs);
! 	  TREE_SIDE_EFFECTS (result) = 1;
! 	  return result;
! 	}
!       else if (! IS_AGGR_TYPE (lhstype))
  	/* Do the default thing */;
        else
  	{
*************** build_modify_expr (lhs, modifycode, rhs)
*** 5808,5816 ****
  
        from_array = TREE_CODE (TREE_TYPE (newrhs)) == ARRAY_TYPE
  	           ? 1 + (modifycode != INIT_EXPR): 0;
!       return (build_vec_init
! 	      (lhs, lhs, array_type_nelts (lhstype), newrhs,
! 	       from_array));
      }
  
    if (modifycode == INIT_EXPR)
--- 5816,5822 ----
  
        from_array = TREE_CODE (TREE_TYPE (newrhs)) == ARRAY_TYPE
  	           ? 1 + (modifycode != INIT_EXPR): 0;
!       return build_vec_init (lhs, newrhs, from_array);
      }
  
    if (modifycode == INIT_EXPR)
*** typeck2.c.~1~	Tue Jan  2 20:15:36 2001
--- typeck2.c	Tue Jan  2 20:15:37 2001
*************** digest_init (type, init, tail)
*** 581,587 ****
  
    if (code == ARRAY_TYPE || IS_AGGR_TYPE_CODE (code))
      {
!       if (raw_constructor && TYPE_NON_AGGREGATE_CLASS (type))
  	{
  	  cp_error ("subobject of type `%T' must be initialized by constructor, not by `%E'",
  		    type, init);
--- 581,588 ----
  
    if (code == ARRAY_TYPE || IS_AGGR_TYPE_CODE (code))
      {
!       if (raw_constructor && TYPE_NON_AGGREGATE_CLASS (type)
! 	  && TREE_HAS_CONSTRUCTOR (init))
  	{
  	  cp_error ("subobject of type `%T' must be initialized by constructor, not by `%E'",
  		    type, init);

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