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:
parent
f5e99456f1
commit
36a68fe705
|
@ -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.
|
||||
|
|
145
gcc/cp/init.c
145
gcc/cp/init.c
|
@ -557,69 +557,40 @@ 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 (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)
|
||||
/* BASETYPE might be an inaccessible direct base (because it
|
||||
is also an indirect base). */
|
||||
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))
|
||||
{
|
||||
/* 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);
|
||||
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);
|
||||
/* 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_CHAIN (last) = NULL_TREE;
|
||||
|
||||
/* 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)
|
|||
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)
|
||||
{
|
||||
basetype = name;
|
||||
name = TYPE_IDENTIFIER (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))
|
||||
/* This is an obsolete unnamed base class initializer. The
|
||||
parser will already have warned about its use. */
|
||||
switch (CLASSTYPE_N_BASECLASSES (type))
|
||||
{
|
||||
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;
|
||||
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);
|
||||
cp_error ("unnamed initializer for `%T', which uses multiple inheritance",
|
||||
type);
|
||||
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);
|
||||
|
||||
/* 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 (name == NULL_TREE)
|
||||
{
|
||||
#if 0
|
||||
if (basetype)
|
||||
name = TYPE_IDENTIFIER (basetype);
|
||||
{
|
||||
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
|
||||
{
|
||||
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))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {}
|
||||
};
|
Loading…
Reference in New Issue