Commit 2282d28d by Mark Mitchell Committed by Mark Mitchell

re PR c++/7188 (Segfault with template class and recursive (incorrect) initalizer list.)

	PR c++/7188.
	* cp-tree.def (CTOR_INITIALIZER): Use one slot, not two.
	* cp-tree.h (emit_base_init): Rename to ....
	(emit_mem_initializers): ... this.
	(expand_member_init): Change prototype.
	* init.c (perform_member_init): Compute explicit, rather than
	requiring it as a parameter.
	(sort_member_init): Rename to ...
	(sort_mem_initializers): ... this.  Process bases and data members
	together.
	(sort_base_init): Remove.
	(emit_base_init): Rename to ...
	(emit_mem_initializers): ... this.
	(expand_aggr_vbase_init_1): Remove.
	(construct_virtual_bases): Rename to ...
	(construct_virtual_base): ... this.
	(expand_member_init): Rework handling of base initializers.
	* method.c (do_build_copy_constructor): Use
	finish_mem_initializers.
	* parse.y (member_init): Adjust calls to expand_member_init.
	* pt.c (tsubst_expr): Simplify CTOR_INITIALIZER case.
	(tsubst_initializer_list): Use expand_member_init.
	* semantics.c (finish_mem_intiailizers): Simplify.

	PR c++/7188.
	* g++.dg/template/meminit1.C: New test.
	* g++.dg/warn/Wreorder-1.C: Likewise.
	* g++.old-deja/g++.mike/warn3.C: Tweak.
	* lib/prune.exp: Ingore "in copy constructor".

From-SVN: r57748
parent 854ef390
2002-10-02 Mark Mitchell <mark@codesourcery.com>
PR c++/7188.
* cp-tree.def (CTOR_INITIALIZER): Use one slot, not two.
* cp-tree.h (emit_base_init): Rename to ....
(emit_mem_initializers): ... this.
(expand_member_init): Change prototype.
* init.c (perform_member_init): Compute explicit, rather than
requiring it as a parameter.
(sort_member_init): Rename to ...
(sort_mem_initializers): ... this. Process bases and data members
together.
(sort_base_init): Remove.
(emit_base_init): Rename to ...
(emit_mem_initializers): ... this.
(expand_aggr_vbase_init_1): Remove.
(construct_virtual_bases): Rename to ...
(construct_virtual_base): ... this.
(expand_member_init): Rework handling of base initializers.
* method.c (do_build_copy_constructor): Use
finish_mem_initializers.
* parse.y (member_init): Adjust calls to expand_member_init.
* pt.c (tsubst_expr): Simplify CTOR_INITIALIZER case.
(tsubst_initializer_list): Use expand_member_init.
* semantics.c (finish_mem_intiailizers): Simplify.
2002-10-02 Roger Sayle <roger@eyesopen.com>
PR optimization/6627
......
......@@ -251,7 +251,7 @@ DEFTREECODE (PSEUDO_DTOR_EXPR, "pseudo_dtor_expr", 'e', 3)
/* CTOR_INITIALIZER is a placeholder in template code for a call to
setup_vtbl_pointer (and appears in all functions, not just ctors). */
DEFTREECODE (CTOR_INITIALIZER, "ctor_initializer", 'e', 2)
DEFTREECODE (CTOR_INITIALIZER, "ctor_initializer", 'e', 1)
DEFTREECODE (RETURN_INIT, "return_init", 'e', 2)
DEFTREECODE (TRY_BLOCK, "try_block", 'e', 2)
DEFTREECODE (EH_SPEC_BLOCK, "eh_spec_block", 'e', 2)
......
......@@ -3845,8 +3845,8 @@ extern void add_friend PARAMS ((tree, tree));
extern tree do_friend PARAMS ((tree, tree, tree, tree, tree, enum overload_flags, tree, int));
/* in init.c */
extern void emit_base_init PARAMS ((tree, tree));
extern tree expand_member_init PARAMS ((tree, tree, tree));
extern tree expand_member_init (tree, tree);
extern void emit_mem_initializers (tree);
extern tree build_aggr_init PARAMS ((tree, tree, int));
extern tree build_init PARAMS ((tree, tree, int));
extern int is_aggr_type PARAMS ((tree, int));
......
......@@ -536,7 +536,6 @@ do_build_copy_constructor (fndecl)
int n_bases = CLASSTYPE_N_BASECLASSES (current_class_type);
tree binfos = TYPE_BINFO_BASETYPES (current_class_type);
tree member_init_list = NULL_TREE;
tree base_init_list = NULL_TREE;
int cvquals = cp_type_quals (TREE_TYPE (parm));
int i;
......@@ -550,10 +549,12 @@ do_build_copy_constructor (fndecl)
{
tree binfo = TREE_VALUE (t);
base_init_list = tree_cons (binfo,
build_base_path (PLUS_EXPR, parm,
binfo, 1),
base_init_list);
member_init_list
= tree_cons (binfo,
build_tree_list (NULL_TREE,
build_base_path (PLUS_EXPR, parm,
binfo, 1)),
member_init_list);
}
for (i = 0; i < n_bases; ++i)
......@@ -562,10 +563,12 @@ do_build_copy_constructor (fndecl)
if (TREE_VIA_VIRTUAL (binfo))
continue;
base_init_list = tree_cons (binfo,
build_base_path (PLUS_EXPR, parm,
binfo, 1),
base_init_list);
member_init_list
= tree_cons (binfo,
build_tree_list (NULL_TREE,
build_base_path (PLUS_EXPR, parm,
binfo, 1)),
member_init_list);
}
for (; fields; fields = TREE_CHAIN (fields))
......@@ -609,9 +612,7 @@ do_build_copy_constructor (fndecl)
member_init_list
= tree_cons (field, init, member_init_list);
}
member_init_list = nreverse (member_init_list);
base_init_list = nreverse (base_init_list);
emit_base_init (member_init_list, base_init_list);
finish_mem_initializers (member_init_list);
}
}
......
......@@ -981,31 +981,27 @@ member_init:
{
if (current_class_name)
pedwarn ("anachronistic old style base class initializer");
$$ = expand_member_init (current_class_ref, NULL_TREE, $2);
$$ = expand_member_init (NULL_TREE, $2);
}
| LEFT_RIGHT
{
if (current_class_name)
pedwarn ("anachronistic old style base class initializer");
$$ = expand_member_init (current_class_ref,
NULL_TREE,
$$ = expand_member_init (NULL_TREE,
void_type_node);
}
| notype_identifier '(' nonnull_exprlist ')'
{ $$ = expand_member_init (current_class_ref, $1, $3); }
{ $$ = expand_member_init ($1, $3); }
| notype_identifier LEFT_RIGHT
{ $$ = expand_member_init (current_class_ref, $1,
void_type_node); }
{ $$ = expand_member_init ($1, void_type_node); }
| nonnested_type '(' nonnull_exprlist ')'
{ $$ = expand_member_init (current_class_ref, $1, $3); }
{ $$ = expand_member_init ($1, $3); }
| nonnested_type LEFT_RIGHT
{ $$ = expand_member_init (current_class_ref, $1,
void_type_node); }
{ $$ = expand_member_init ($1, void_type_node); }
| typename_sub '(' nonnull_exprlist ')'
{ $$ = expand_member_init (current_class_ref, $1, $3); }
{ $$ = expand_member_init ($1, $3); }
| typename_sub LEFT_RIGHT
{ $$ = expand_member_init (current_class_ref, $1,
void_type_node); }
{ $$ = expand_member_init ($1, void_type_node); }
| error
{ $$ = NULL_TREE; }
;
......
......@@ -7369,18 +7369,10 @@ tsubst_expr (t, args, complain, in_decl)
break;
case CTOR_INITIALIZER:
{
tree member_init_list;
tree base_init_list;
prep_stmt (t);
member_init_list
= tsubst_initializer_list (TREE_OPERAND (t, 0), args);
base_init_list
= tsubst_initializer_list (TREE_OPERAND (t, 1), args);
emit_base_init (member_init_list, base_init_list);
break;
}
prep_stmt (t);
finish_mem_initializers (tsubst_initializer_list
(TREE_OPERAND (t, 0), args));
break;
case RETURN_STMT:
prep_stmt (t);
......@@ -10293,8 +10285,7 @@ static tree
tsubst_initializer_list (t, argvec)
tree t, argvec;
{
tree first = NULL_TREE;
tree *p = &first;
tree inits = NULL_TREE;
for (; t; t = TREE_CHAIN (t))
{
......@@ -10312,13 +10303,17 @@ tsubst_initializer_list (t, argvec)
else if (TREE_CODE (init) == TREE_LIST)
for (val = init; val; val = TREE_CHAIN (val))
TREE_VALUE (val) = convert_from_reference (TREE_VALUE (val));
else
else if (init != void_type_node)
init = convert_from_reference (init);
*p = build_tree_list (decl, init);
p = &TREE_CHAIN (*p);
init = expand_member_init (decl, init);
if (init)
{
TREE_CHAIN (init) = inits;
inits = init;
}
}
return first;
return inits;
}
/* Set CURRENT_ACCESS_SPECIFIER based on the protection of DECL. */
......
......@@ -1094,67 +1094,21 @@ begin_mem_initializers ()
error ("only constructors take base initializers");
}
/* The INIT_LIST is a list of mem-initializers, in the order they were
written by the user. The TREE_VALUE of each node is a list of
initializers for a particular subobject. The TREE_PURPOSE is a
FIELD_DECL is the initializer is for a non-static data member, and
a class type if the initializer is for a base class. */
/* The MEM_INITS is a list of mem-initializers, in reverse of the
order they were written by the user. Each node is as for
emit_mem_initializers. */
void
finish_mem_initializers (init_list)
tree init_list;
finish_mem_initializers (tree mem_inits)
{
tree member_init_list;
tree base_init_list;
tree last_base_warned_about;
tree next;
tree init;
member_init_list = NULL_TREE;
base_init_list = NULL_TREE;
last_base_warned_about = NULL_TREE;
for (init = init_list; init; init = next)
{
next = TREE_CHAIN (init);
if (TREE_CODE (TREE_PURPOSE (init)) == FIELD_DECL)
{
TREE_CHAIN (init) = member_init_list;
member_init_list = init;
/* We're running through the initializers from right to left
as we process them here. So, if we see a data member
initializer after we see a base initializer, that
actually means that the base initializer preceded the
data member initializer. */
if (warn_reorder && last_base_warned_about != base_init_list)
{
tree base;
for (base = base_init_list;
base != last_base_warned_about;
base = TREE_CHAIN (base))
{
warning ("base initializer for `%T'",
TREE_PURPOSE (base));
warning (" will be re-ordered to precede member initializations");
}
last_base_warned_about = base_init_list;
}
}
else
{
TREE_CHAIN (init) = base_init_list;
base_init_list = init;
}
}
/* Reorder the MEM_INITS so that they are in the order they appeared
in the source program. */
mem_inits = nreverse (mem_inits);
if (processing_template_decl)
add_stmt (build_min_nt (CTOR_INITIALIZER,
member_init_list, base_init_list));
add_stmt (build_min_nt (CTOR_INITIALIZER, mem_inits));
else
emit_base_init (member_init_list, base_init_list);
emit_mem_initializers (mem_inits);
}
/* Returns the stack of SCOPE_STMTs for the current function. */
......
2002-10-02 Mark Mitchell <mark@codesourcery.com>
PR c++/7188.
* g++.dg/template/meminit1.C: New test.
* g++.dg/warn/Wreorder-1.C: Likewise.
* g++.old-deja/g++.mike/warn3.C: Tweak.
* lib/prune.exp: Ingore "in copy constructor".
2002-10-02 Andreas Jaeger <aj@suse.de>
* gcc.dg/20020919-1.c, gcc.dg/inline-2.c, gcc.dg/980211-1.c,
......
template <class T >
struct S
{
S() : S() {} // { dg-error "base" }
};
S<int> s; // { dg-error "instantiated" }
// { dg-options "-Wreorder -W" }
struct S {
S ();
};
struct T {
T ();
};
struct U : virtual public S, virtual public T {
U () : T (), S () {} // { dg-warning "" }
U (const U&) : S () {} // { dg-warning "copy" }
};
......@@ -7,6 +7,6 @@ public:
};
class D : public B {
int member;
int member; // WARNING - reordered
D() : member(0), B(member) { } // WARNING - reordered
};
# Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc.
# Copyright (C) 1997, 1999, 2000, 2002 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
......@@ -19,7 +19,7 @@
proc prune_gcc_output { text } {
#send_user "Before:$text\n"
regsub -all "(^|\n)\[^\n\]*: In (function|member|method|constructor|instantiation|program|subroutine|block-data) \[^\n\]*" $text "" text
regsub -all "(^|\n)\[^\n\]*: In (function|member|method|(copy )?constructor|instantiation|program|subroutine|block-data) \[^\n\]*" $text "" text
regsub -all "(^|\n)\[^\n\]*: At (top level|global scope):\[^\n\]*" $text "" text
regsub -all "(^|\n)collect2: ld returned \[^\n\]*" $text "" text
regsub -all "(^|\n)Please submit.*instructions\[^\n\]*" $text "" text
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment