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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH: PR 9879


This patch fixes PR c++/9879.  Tested on i686-pc-linux-gnu, applied on
the mainline and on the branch.

--
Mark Mitchell
CodeSourcery, LLC
mark at codesourcery dot com

2003-02-28  Mark Mitchell  <mark at codesourcery dot com>

	PR c++/9879
	* cp-tree.h (build_zero_init): Add parameter.
	* decl.c (cp_finish_decl): Adjust call.
	* init.c (build_zero_init): Add nelts parameter.  Adjust recursive
	calls.
	(build_default_init): Add nelts parameter.  Adjust calls to
	build_zero_init.
	(build_new_1): Adjust call to build_default_init.
	* typeck2.c (process_init_constructor): Adjust call to build_zero_init.

2003-02-28  Mark Mitchell  <mark at codesourcery dot com>

	PR c++/9879
	* testsuite/g++.dg/init/new4.C: New test.

Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.815
diff -c -5 -p -r1.815 cp-tree.h
*** cp/cp-tree.h	24 Feb 2003 21:51:57 -0000	1.815
--- cp/cp-tree.h	28 Feb 2003 19:33:06 -0000
*************** extern void emit_mem_initializers		(tree
*** 3910,3920 ****
  extern tree build_aggr_init			(tree, tree, int);
  extern tree build_init				(tree, tree, int);
  extern int is_aggr_type				(tree, int);
  extern tree get_aggr_from_typedef		(tree, int);
  extern tree get_type_value			(tree);
! extern tree build_zero_init       		(tree, bool);
  extern tree build_member_call			(tree, tree, tree);
  extern tree build_offset_ref			(tree, tree);
  extern tree resolve_offset_ref			(tree);
  extern tree build_new				(tree, tree, tree, int);
  extern tree build_vec_init			(tree, tree, tree, int);
--- 3910,3920 ----
  extern tree build_aggr_init			(tree, tree, int);
  extern tree build_init				(tree, tree, int);
  extern int is_aggr_type				(tree, int);
  extern tree get_aggr_from_typedef		(tree, int);
  extern tree get_type_value			(tree);
! extern tree build_zero_init       		(tree, tree, bool);
  extern tree build_member_call			(tree, tree, tree);
  extern tree build_offset_ref			(tree, tree);
  extern tree resolve_offset_ref			(tree);
  extern tree build_new				(tree, tree, tree, int);
  extern tree build_vec_init			(tree, tree, tree, int);
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1005
diff -c -5 -p -r1.1005 decl.c
*** cp/decl.c	26 Feb 2003 22:14:24 -0000	1.1005
--- cp/decl.c	28 Feb 2003 19:33:08 -0000
*************** cp_finish_decl (tree decl, tree init, tr
*** 8207,8216 ****
--- 8207,8217 ----
  	     the type of DECL is finalized.  If DECL_INITIAL is set,
  	     then the DECL is statically initialized, and any
  	     necessary zero-initialization has already been performed.  */
  	  if (TREE_STATIC (decl) && !DECL_INITIAL (decl))
  	    DECL_INITIAL (decl) = build_zero_init (TREE_TYPE (decl),
+ 						   /*nelts=*/NULL_TREE,
  						   /*static_storage_p=*/true);
  	  /* Remember that the initialization for this variable has
  	     taken place.  */
  	  DECL_INITIALIZED_P (decl) = 1;
  	}
Index: cp/init.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/init.c,v
retrieving revision 1.310
diff -c -5 -p -r1.310 init.c
*** cp/init.c	20 Feb 2003 17:51:43 -0000	1.310
--- cp/init.c	28 Feb 2003 19:33:09 -0000
*************** static void expand_virtual_init PARAMS (
*** 46,56 ****
  static tree sort_mem_initializers (tree, tree);
  static tree initializing_context PARAMS ((tree));
  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));
  static tree build_field_list PARAMS ((tree, tree, int *));
  static tree build_vtbl_address PARAMS ((tree));
--- 46,56 ----
  static tree sort_mem_initializers (tree, tree);
  static tree initializing_context PARAMS ((tree));
  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, 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));
  static tree build_field_list PARAMS ((tree, tree, int *));
  static tree build_vtbl_address PARAMS ((tree));
*************** initialize_vtbl_ptrs (addr)
*** 157,172 ****
  /* Return an expression for the zero-initialization of an object with
     type T.  This expression will either be a constant (in the case
     that T is a scalar), or a CONSTRUCTOR (in the case that T is an
     aggregate).  In either case, the value can be used as DECL_INITIAL
     for a decl of the indicated TYPE; it is a valid static initializer.
!    If STATIC_STORAGE_P is TRUE, initializers are only generated for
!    entities for which zero-initialization does not simply mean filling
!    the storage with zero bytes.  */
  
  tree
! build_zero_init (tree type, bool static_storage_p)
  {
    tree init = NULL_TREE;
  
    /* [dcl.init]
  
--- 157,174 ----
  /* Return an expression for the zero-initialization of an object with
     type T.  This expression will either be a constant (in the case
     that T is a scalar), or a CONSTRUCTOR (in the case that T is an
     aggregate).  In either case, the value can be used as DECL_INITIAL
     for a decl of the indicated TYPE; it is a valid static initializer.
!    If NELTS is non-NULL, and TYPE is an ARRAY_TYPE, NELTS is the
!    number of elements in the array.  If STATIC_STORAGE_P is TRUE,
!    initializers are only generated for entities for which
!    zero-initialization does not simply mean filling the storage with
!    zero bytes.  */
  
  tree
! build_zero_init (tree type, tree nelts, bool static_storage_p)
  {
    tree init = NULL_TREE;
  
    /* [dcl.init]
  
*************** build_zero_init (tree type, bool static_
*** 215,224 ****
--- 217,227 ----
  	     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)
*************** build_zero_init (tree type, bool static_
*** 234,248 ****
  
        /* Build a constructor to contain the initializations.  */
        init = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE);
        /* Iterate over the array elements, building initializations.  */
        inits = NULL_TREE;
!       for (index = size_zero_node, max_index = array_type_nelts (type);
  	   !tree_int_cst_lt (max_index, index);
  	   index = size_binop (PLUS_EXPR, index, size_one_node))
  	inits = tree_cons (index,
! 			   build_zero_init (TREE_TYPE (type), 
  					    static_storage_p),
  			   inits);
        CONSTRUCTOR_ELTS (init) = nreverse (inits);
      }
    else if (TREE_CODE (type) == REFERENCE_TYPE)
--- 237,253 ----
  
        /* Build a constructor to contain the initializations.  */
        init = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE);
        /* Iterate over the array elements, building initializations.  */
        inits = NULL_TREE;
!       max_index = nelts ? nelts : array_type_nelts (type);
!       for (index = size_zero_node;
  	   !tree_int_cst_lt (max_index, index);
  	   index = size_binop (PLUS_EXPR, index, size_one_node))
  	inits = tree_cons (index,
! 			   build_zero_init (TREE_TYPE (type),
! 					    /*nelts=*/NULL_TREE,
  					    static_storage_p),
  			   inits);
        CONSTRUCTOR_ELTS (init) = nreverse (inits);
      }
    else if (TREE_CODE (type) == REFERENCE_TYPE)
*************** build_zero_init (tree type, bool static_
*** 255,272 ****
      TREE_CONSTANT (init) = 1;
  
    return init;
  }
  
! /* Build an expression for the default-initialization of an object
!    with type T.  If initialization T requires calling constructors,
!    this function returns NULL_TREE; the caller is responsible for
!    arranging for the constructors to be called.  */
  
  static tree
! build_default_init (type)
       tree type;
  {
    /* [dcl.init]:
  
      To default-initialize an object of type T means:
  
--- 260,280 ----
      TREE_CONSTANT (init) = 1;
  
    return init;
  }
  
! /* Build an expression for the default-initialization of an object of
!    the indicated TYPE.  If NELTS is non-NULL, and TYPE is an
!    ARRAY_TYPE, NELTS is the number of elements in the array.  If
!    initialization of TYPE requires calling constructors, this function
!    returns NULL_TREE; the caller is responsible for arranging for the
!    constructors to be called.  */
  
  static tree
! build_default_init (type, nelts)
       tree type;
+      tree nelts;
  {
    /* [dcl.init]:
  
      To default-initialize an object of type T means:
  
*************** build_default_init (type)
*** 296,306 ****
    if (TYPE_NEEDS_CONSTRUCTING (type))
      return NULL_TREE;
        
    /* At this point, TYPE is either a POD class type, an array of POD
       classes, or something even more inoccuous.  */
!   return build_zero_init (type, /*static_storage_p=*/false);
  }
  
  /* Initialize MEMBER, a FIELD_DECL, with INIT, a TREE_LIST of
     arguments.  If TREE_LIST is void_type_node, an empty initializer
     list was given; if NULL_TREE no initializer was given.  */
--- 304,314 ----
    if (TYPE_NEEDS_CONSTRUCTING (type))
      return NULL_TREE;
        
    /* At this point, TYPE is either a POD class type, an array of POD
       classes, or something even more inoccuous.  */
!   return build_zero_init (type, nelts, /*static_storage_p=*/false);
  }
  
  /* Initialize MEMBER, a FIELD_DECL, with INIT, a TREE_LIST of
     arguments.  If TREE_LIST is void_type_node, an empty initializer
     list was given; if NULL_TREE no initializer was given.  */
*************** perform_member_init (tree member, tree i
*** 362,372 ****
      {
        if (init == NULL_TREE)
  	{
  	  if (explicit)
  	    {
! 	      init = build_default_init (type);
  	      if (TREE_CODE (type) == REFERENCE_TYPE)
  		warning
  		  ("default-initialization of `%#D', which has reference type",
  		   member);
  	    }
--- 370,380 ----
      {
        if (init == NULL_TREE)
  	{
  	  if (explicit)
  	    {
! 	      init = build_default_init (type, /*nelts=*/NULL_TREE);
  	      if (TREE_CODE (type) == REFERENCE_TYPE)
  		warning
  		  ("default-initialization of `%#D', which has reference type",
  		   member);
  	    }
*************** build_new_1 (exp)
*** 2365,2375 ****
    if (TYPE_NEEDS_CONSTRUCTING (type) || init)
      {
        init_expr = build_indirect_ref (alloc_node, NULL);
  
        if (init == void_zero_node)
! 	init = build_default_init (full_type);
        else if (init && pedantic && has_array)
  	pedwarn ("ISO C++ forbids initialization in array new");
  
        if (has_array)
  	init_expr
--- 2373,2383 ----
    if (TYPE_NEEDS_CONSTRUCTING (type) || init)
      {
        init_expr = build_indirect_ref (alloc_node, NULL);
  
        if (init == void_zero_node)
! 	init = build_default_init (full_type, nelts);
        else if (init && pedantic && has_array)
  	pedwarn ("ISO C++ forbids initialization in array new");
  
        if (has_array)
  	init_expr
Index: cp/typeck2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/typeck2.c,v
retrieving revision 1.137
diff -c -5 -p -r1.137 typeck2.c
*** cp/typeck2.c	24 Feb 2003 15:47:21 -0000	1.137
--- cp/typeck2.c	28 Feb 2003 19:33:10 -0000
*************** process_init_constructor (type, init, el
*** 731,740 ****
--- 731,741 ----
  		next1 = build (CONSTRUCTOR, NULL_TREE, 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;
*************** process_init_constructor (type, init, el
*** 849,858 ****
--- 850,860 ----
  	          && (!init || TREE_HAS_CONSTRUCTOR (init)))
  		warning ("missing initializer for member `%D'", 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;
Index: testsuite/g++.dg/init/new4.C
===================================================================
RCS file: testsuite/g++.dg/init/new4.C
diff -N testsuite/g++.dg/init/new4.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/init/new4.C	28 Feb 2003 19:33:10 -0000
***************
*** 0 ****
--- 1 ----
+ int *x = new int [2] ();


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