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>
* 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)
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);
/* 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 if (is_aggr_type (basetype, 1))
else
{
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;
}
}
/* 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;
}
else
my_friendly_abort (365);
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.
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.
/* 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.
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)
{
basetype = name;
name = TYPE_IDENTIFIER (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 (name && TREE_CODE (name) == TYPE_DECL)
else if (TYPE_P (name))
{
basetype = TYPE_MAIN_VARIANT (TREE_TYPE (name));
name = DECL_NAME (name);
basetype = name;
name = TYPE_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 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 (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 (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))
......
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
......
// { 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