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,69 +557,40 @@ sort_base_init (t, base_init_list, rbase_ptr, vbase_ptr) ...@@ -557,69 +557,40 @@ 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 (basetype == NULL_TREE)
{
/* 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) if (binfo == NULL_TREE)
/* BASETYPE might be an inaccessible direct base (because it
is also an indirect base). */
continue; 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)) if (TREE_VIA_VIRTUAL (binfo))
{ {
/* 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); tree v = binfo_for_vbase (BINFO_TYPE (binfo), t);
vbases = tree_cons (v, TREE_VALUE (x), vbases); vbases = tree_cons (v, TREE_VALUE (x), vbases);
continue;
} }
else else
{ {
/* Otherwise, if it is not an immediate base class, complain. */ /* Otherwise, it must be an immediate base class. */
for (i = n_baseclasses-1; i >= 0; i--) my_friendly_assert
if (BINFO_TYPE (binfo) == BINFO_TYPE (TREE_VEC_ELT (binfos, i))) (same_type_p (BINFO_TYPE (BINFO_INHERITANCE_CHAIN (binfo)),
break; t), 20011113);
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_PURPOSE (x) = binfo;
TREE_CHAIN (last) = x; TREE_CHAIN (last) = x;
last = x; last = x;
} }
}
TREE_CHAIN (last) = NULL_TREE; TREE_CHAIN (last) = NULL_TREE;
/* Now walk through our regular bases and make sure they're initialized. */ /* Now walk through our regular bases and make sure they're initialized. */
...@@ -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
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 An old style unnamed direct single base construction is permitted,
to look for NAME, because if it's in that list, it will be handled where NAME is NULL. */
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. */
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. */
}
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)) switch (CLASSTYPE_N_BASECLASSES (type))
{ {
case 0: case 0:
error ("base class initializer specified, but no base class to initialize"); cp_error ("unnamed initializer for `%T', which has no base classes",
type);
return NULL_TREE; return NULL_TREE;
case 1: case 1:
basetype = TYPE_BINFO_BASETYPE (type, 0); basetype = TYPE_BINFO_BASETYPE (type, 0);
break; break;
default: default:
error ("initializer for unnamed base class ambiguous"); cp_error ("unnamed initializer for `%T', which uses multiple inheritance",
cp_error ("(type `%T' uses multiple inheritance)", type); type);
return NULL_TREE; return NULL_TREE;
} }
}
else if (TYPE_P (name))
{
basetype = name;
name = TYPE_NAME (name);
}
else if (TREE_CODE (name) == TYPE_DECL)
basetype = TYPE_MAIN_VARIANT (TREE_TYPE (name));
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 (name == NULL_TREE)
{
#if 0
if (basetype) if (basetype)
name = TYPE_IDENTIFIER (basetype);
else
{ {
error ("no base class to initialize"); if (current_template_parms)
return; ;
} else if (vec_binfo_member (basetype, TYPE_BINFO_BASETYPES (type)))
#endif /* A direct base. */;
} else if (binfo_for_vbase (basetype, type))
else if (basetype != type /* A virtual base. */;
&& ! current_template_parms else
&& ! 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