This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: PR 9879
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 28 Feb 2003 12:22:42 -0800
- Subject: C++ PATCH: PR 9879
- Reply-to: mark at codesourcery dot com
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] ();