re PR c++/3154 (Tree check: expected class 't', have 'd' (type_decl) in is_aggr_type, at cp/init.c:1435)

cp:
	PR g++/3154
	* init.c (sort_base_init): Remove unreachable code.
	(expand_member_init): Adjust comment to reflect reality. Simplify
	and remove unreachable code.
testsuite:
	* g++.dg/other/init1.C: New test.

From-SVN: r47047
This commit is contained in:
Nathan Sidwell 2001-11-15 10:03:41 +00:00 committed by Nathan Sidwell
parent f5e99456f1
commit 36a68fe705
4 changed files with 107 additions and 115 deletions

View File

@ -1,3 +1,10 @@
2001-11-15 Nathan Sidwell <nathan@codesourcery.com>
PR g++/3154
* init.c (sort_base_init): Remove unreachable code.
(expand_member_init): Adjust comment to reflect reality. Simplify
and remove unreachable code.
2001-11-15 Neil Booth <neil@daikokuya.demon.co.uk>
* cp-tree.h (init_reswords, cxx_init_decl_processing): New.

View File

@ -557,68 +557,39 @@ sort_base_init (t, base_init_list, rbase_ptr, vbase_ptr)
tree vbases = NULL_TREE;
/* First walk through and splice out vbase and invalid initializers.
Also replace names with binfos. */
Also replace types with binfos. */
last = tree_cons (NULL_TREE, NULL_TREE, base_init_list);
for (x = TREE_CHAIN (last); x; x = TREE_CHAIN (x))
{
tree basetype = TREE_PURPOSE (x);
tree binfo = NULL_TREE;
tree binfo = binfo_or_else (basetype, t);
if (binfo == NULL_TREE)
/* BASETYPE might be an inaccessible direct base (because it
is also an indirect base). */
continue;
if (basetype == NULL_TREE)
if (TREE_VIA_VIRTUAL (binfo))
{
/* Initializer for single base class. Must not
use multiple inheritance or this is ambiguous. */
switch (n_baseclasses)
{
case 0:
cp_error ("`%T' does not have a base class to initialize",
current_class_type);
return;
case 1:
break;
default:
cp_error ("unnamed initializer ambiguous for `%T' which uses multiple inheritance",
current_class_type);
return;
}
binfo = TREE_VEC_ELT (binfos, 0);
}
else if (is_aggr_type (basetype, 1))
{
binfo = binfo_or_else (basetype, t);
if (binfo == NULL_TREE)
continue;
/* Virtual base classes are special cases. Their initializers
are recorded with this constructor, and they are used when
this constructor is the top-level constructor called. */
if (TREE_VIA_VIRTUAL (binfo))
{
tree v = binfo_for_vbase (BINFO_TYPE (binfo), t);
vbases = tree_cons (v, TREE_VALUE (x), vbases);
continue;
}
else
{
/* Otherwise, if it is not an immediate base class, complain. */
for (i = n_baseclasses-1; i >= 0; i--)
if (BINFO_TYPE (binfo) == BINFO_TYPE (TREE_VEC_ELT (binfos, i)))
break;
if (i < 0)
{
cp_error ("`%T' is not an immediate base class of `%T'",
basetype, current_class_type);
continue;
}
}
/* Virtual base classes are special cases. Their
initializers are recorded with this constructor, and they
are used when this constructor is the top-level
constructor called. */
tree v = binfo_for_vbase (BINFO_TYPE (binfo), t);
vbases = tree_cons (v, TREE_VALUE (x), vbases);
}
else
my_friendly_abort (365);
{
/* Otherwise, it must be an immediate base class. */
my_friendly_assert
(same_type_p (BINFO_TYPE (BINFO_INHERITANCE_CHAIN (binfo)),
t), 20011113);
TREE_PURPOSE (x) = binfo;
TREE_CHAIN (last) = x;
last = x;
TREE_PURPOSE (x) = binfo;
TREE_CHAIN (last) = x;
last = x;
}
}
TREE_CHAIN (last) = NULL_TREE;
@ -1039,17 +1010,16 @@ member_init_ok_or_else (field, type, member_name)
return 1;
}
/* If NAME is a viable field name for the aggregate DECL,
and PARMS is a viable parameter list, then expand an _EXPR
which describes this initialization.
/* EXP is an expression of aggregate type. NAME is an IDENTIFIER_NODE
which names a field, or it is a _TYPE node or TYPE_DECL which names
a base for that type. INIT is a parameter list for that field's or
base's constructor. Check the validity of NAME, and return a
TREE_LIST of the base _TYPE or FIELD_DECL and the INIT. EXP is used
only to get its type. If NAME is invalid, return NULL_TREE and
issue a diagnostic.
Note that we do not need to chase through the class's base classes
to look for NAME, because if it's in that list, it will be handled
by the constructor for that base class.
We do not yet have a fixed-point finder to instantiate types
being fed to overloaded constructors. If there is a unique
constructor, then argument types can be got from that one. */
An old style unnamed direct single base construction is permitted,
where NAME is NULL. */
tree
expand_member_init (exp, name, init)
@ -1062,72 +1032,56 @@ expand_member_init (exp, name, init)
return NULL_TREE;
type = TYPE_MAIN_VARIANT (TREE_TYPE (exp));
my_friendly_assert (IS_AGGR_TYPE (type), 20011113);
if (name && TYPE_P (name))
if (!name)
{
/* This is an obsolete unnamed base class initializer. The
parser will already have warned about its use. */
switch (CLASSTYPE_N_BASECLASSES (type))
{
case 0:
cp_error ("unnamed initializer for `%T', which has no base classes",
type);
return NULL_TREE;
case 1:
basetype = TYPE_BINFO_BASETYPE (type, 0);
break;
default:
cp_error ("unnamed initializer for `%T', which uses multiple inheritance",
type);
return NULL_TREE;
}
}
else if (TYPE_P (name))
{
basetype = name;
name = TYPE_IDENTIFIER (name);
name = TYPE_NAME (name);
}
else if (name && TREE_CODE (name) == TYPE_DECL)
{
basetype = TYPE_MAIN_VARIANT (TREE_TYPE (name));
name = DECL_NAME (name);
}
if (name == NULL_TREE && IS_AGGR_TYPE (type))
switch (CLASSTYPE_N_BASECLASSES (type))
{
case 0:
error ("base class initializer specified, but no base class to initialize");
return NULL_TREE;
case 1:
basetype = TYPE_BINFO_BASETYPE (type, 0);
break;
default:
error ("initializer for unnamed base class ambiguous");
cp_error ("(type `%T' uses multiple inheritance)", type);
return NULL_TREE;
}
else if (TREE_CODE (name) == TYPE_DECL)
basetype = TYPE_MAIN_VARIANT (TREE_TYPE (name));
my_friendly_assert (init != NULL_TREE, 0);
/* The grammar should not allow fields which have names that are
TYPENAMEs. Therefore, if the field has a non-NULL TREE_TYPE, we
may assume that this is an attempt to initialize a base class
member of the current type. Otherwise, it is an attempt to
initialize a member field. */
if (init == void_type_node)
init = NULL_TREE;
if (name == NULL_TREE || basetype)
if (basetype)
{
if (name == NULL_TREE)
if (current_template_parms)
;
else if (vec_binfo_member (basetype, TYPE_BINFO_BASETYPES (type)))
/* A direct base. */;
else if (binfo_for_vbase (basetype, type))
/* A virtual base. */;
else
{
#if 0
if (basetype)
name = TYPE_IDENTIFIER (basetype);
else
{
error ("no base class to initialize");
return;
}
#endif
}
else if (basetype != type
&& ! current_template_parms
&& ! vec_binfo_member (basetype,
TYPE_BINFO_BASETYPES (type))
&& ! binfo_for_vbase (basetype, type))
{
if (IDENTIFIER_CLASS_VALUE (name))
goto try_member;
if (TYPE_USES_VIRTUAL_BASECLASSES (type))
cp_error ("type `%T' is not an immediate or virtual basetype for `%T'",
basetype, type);
cp_error ("type `%D' is not a direct or virtual base of `%T'",
name, type);
else
cp_error ("type `%T' is not an immediate basetype for `%T'",
basetype, type);
cp_error ("type `%D' is not a direct base of `%T'",
name, type);
return NULL_TREE;
}
@ -1135,7 +1089,6 @@ expand_member_init (exp, name, init)
}
else
{
try_member:
field = lookup_field (type, name, 1, 0);
if (! member_init_ok_or_else (field, type, name))

View File

@ -1,3 +1,7 @@
2001-11-15 Nathan Sidwell <nathan@codesourcery.com>
* g++.dg/other/init1.C: New test.
2001-11-14 Geoffrey Keating <geoffk@redhat.com>
* gcc.dg/noncompile/920923-1.c: xstormy16 produces an extra error

View File

@ -0,0 +1,28 @@
// { dg-do compile }
// Copyright (C) 2001 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 13 Nov 2001 <nathan@codesourcery.com>
// Bug 3154
class A {};
struct B : A
{
typedef A Parent;
B () : Parent () {};
};
class T
{
typedef int Foo;
T () : Foo () {} // { dg-error "type `T::Foo' is not" "" }
};
struct S : B
{
int Parent;
S () :Parent (1) {}
};