aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@codesourcery.com>2001-11-15 10:03:41 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2001-11-15 10:03:41 +0000
commit36a68fe705785961c143e33c0d52aa4d4ef85097 (patch)
tree0641d81cf0e6078472b02b99684118322500976f
parentf5e99456f19b80978984f781e1d847b90d09b30a (diff)
downloadgcc-36a68fe705785961c143e33c0d52aa4d4ef85097.zip
gcc-36a68fe705785961c143e33c0d52aa4d4ef85097.tar.gz
gcc-36a68fe705785961c143e33c0d52aa4d4ef85097.tar.bz2
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
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/init.c181
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.dg/other/init1.C28
4 files changed, 106 insertions, 114 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 7c856b4..025defa 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 8dad82d..fdb3557 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -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))
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 924e3b1..e544dcc 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/g++.dg/other/init1.C b/gcc/testsuite/g++.dg/other/init1.C
new file mode 100644
index 0000000..bf4c079
--- /dev/null
+++ b/gcc/testsuite/g++.dg/other/init1.C
@@ -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) {}
+};