Commit 36a68fe7 by Nathan Sidwell Committed by Nathan Sidwell

re PR c++/3154 (Tree check: expected class 't', have 'd' (type_decl) in…

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
parent f5e99456
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> 2001-11-15 Neil Booth <neil@daikokuya.demon.co.uk>
* cp-tree.h (init_reswords, cxx_init_decl_processing): New. * cp-tree.h (init_reswords, cxx_init_decl_processing): New.
......
...@@ -557,68 +557,39 @@ sort_base_init (t, base_init_list, rbase_ptr, vbase_ptr) ...@@ -557,68 +557,39 @@ sort_base_init (t, base_init_list, rbase_ptr, vbase_ptr)
tree vbases = NULL_TREE; tree vbases = NULL_TREE;
/* First walk through and splice out vbase and invalid initializers. /* 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); last = tree_cons (NULL_TREE, NULL_TREE, base_init_list);
for (x = TREE_CHAIN (last); x; x = TREE_CHAIN (x)) for (x = TREE_CHAIN (last); x; x = TREE_CHAIN (x))
{ {
tree basetype = TREE_PURPOSE (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 /* Virtual base classes are special cases. Their
use multiple inheritance or this is ambiguous. */ initializers are recorded with this constructor, and they
switch (n_baseclasses) are used when this constructor is the top-level
{ constructor called. */
case 0: tree v = binfo_for_vbase (BINFO_TYPE (binfo), t);
cp_error ("`%T' does not have a base class to initialize", vbases = tree_cons (v, TREE_VALUE (x), vbases);
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)) else
{ {
binfo = binfo_or_else (basetype, t); /* Otherwise, it must be an immediate base class. */
if (binfo == NULL_TREE) my_friendly_assert
continue; (same_type_p (BINFO_TYPE (BINFO_INHERITANCE_CHAIN (binfo)),
t), 20011113);
/* Virtual base classes are special cases. Their initializers
are recorded with this constructor, and they are used when TREE_PURPOSE (x) = binfo;
this constructor is the top-level constructor called. */ TREE_CHAIN (last) = x;
if (TREE_VIA_VIRTUAL (binfo)) last = x;
{
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;
}
}
} }
else
my_friendly_abort (365);
TREE_PURPOSE (x) = binfo;
TREE_CHAIN (last) = x;
last = x;
} }
TREE_CHAIN (last) = NULL_TREE; TREE_CHAIN (last) = NULL_TREE;
...@@ -1039,17 +1010,16 @@ member_init_ok_or_else (field, type, member_name) ...@@ -1039,17 +1010,16 @@ member_init_ok_or_else (field, type, member_name)
return 1; return 1;
} }
/* If NAME is a viable field name for the aggregate DECL, /* EXP is an expression of aggregate type. NAME is an IDENTIFIER_NODE
and PARMS is a viable parameter list, then expand an _EXPR which names a field, or it is a _TYPE node or TYPE_DECL which names
which describes this initialization. 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
Note that we do not need to chase through the class's base classes TREE_LIST of the base _TYPE or FIELD_DECL and the INIT. EXP is used
to look for NAME, because if it's in that list, it will be handled only to get its type. If NAME is invalid, return NULL_TREE and
by the constructor for that base class. issue a diagnostic.
We do not yet have a fixed-point finder to instantiate types An old style unnamed direct single base construction is permitted,
being fed to overloaded constructors. If there is a unique where NAME is NULL. */
constructor, then argument types can be got from that one. */
tree tree
expand_member_init (exp, name, init) expand_member_init (exp, name, init)
...@@ -1062,72 +1032,56 @@ expand_member_init (exp, name, init) ...@@ -1062,72 +1032,56 @@ expand_member_init (exp, name, init)
return NULL_TREE; return NULL_TREE;
type = TYPE_MAIN_VARIANT (TREE_TYPE (exp)); type = TYPE_MAIN_VARIANT (TREE_TYPE (exp));
my_friendly_assert (IS_AGGR_TYPE (type), 20011113);
if (name && TYPE_P (name)) if (!name)
{ {
basetype = name; /* This is an obsolete unnamed base class initializer. The
name = TYPE_IDENTIFIER (name); 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 (name && TREE_CODE (name) == TYPE_DECL) else if (TYPE_P (name))
{ {
basetype = TYPE_MAIN_VARIANT (TREE_TYPE (name)); basetype = name;
name = DECL_NAME (name); name = TYPE_NAME (name);
} }
else if (TREE_CODE (name) == TYPE_DECL)
if (name == NULL_TREE && IS_AGGR_TYPE (type)) basetype = TYPE_MAIN_VARIANT (TREE_TYPE (name));
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;
}
my_friendly_assert (init != NULL_TREE, 0); 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) if (init == void_type_node)
init = NULL_TREE; init = NULL_TREE;
if (name == NULL_TREE || basetype) if (basetype)
{ {
if (name == NULL_TREE) if (current_template_parms)
{ ;
#if 0 else if (vec_binfo_member (basetype, TYPE_BINFO_BASETYPES (type)))
if (basetype) /* A direct base. */;
name = TYPE_IDENTIFIER (basetype); else if (binfo_for_vbase (basetype, type))
else /* A virtual base. */;
{ 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)) if (TYPE_USES_VIRTUAL_BASECLASSES (type))
cp_error ("type `%T' is not an immediate or virtual basetype for `%T'", cp_error ("type `%D' is not a direct or virtual base of `%T'",
basetype, type); name, type);
else else
cp_error ("type `%T' is not an immediate basetype for `%T'", cp_error ("type `%D' is not a direct base of `%T'",
basetype, type); name, type);
return NULL_TREE; return NULL_TREE;
} }
...@@ -1135,7 +1089,6 @@ expand_member_init (exp, name, init) ...@@ -1135,7 +1089,6 @@ expand_member_init (exp, name, init)
} }
else else
{ {
try_member:
field = lookup_field (type, name, 1, 0); field = lookup_field (type, name, 1, 0);
if (! member_init_ok_or_else (field, type, name)) if (! member_init_ok_or_else (field, type, name))
......
2001-11-15 Nathan Sidwell <nathan@codesourcery.com>
* g++.dg/other/init1.C: New test.
2001-11-14 Geoffrey Keating <geoffk@redhat.com> 2001-11-14 Geoffrey Keating <geoffk@redhat.com>
* gcc.dg/noncompile/920923-1.c: xstormy16 produces an extra error * gcc.dg/noncompile/920923-1.c: xstormy16 produces an extra error
......
// { 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) {}
};
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