summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorLee Millward <lmillward@gcc.gnu.org>2006-10-17 23:22:14 +0000
committerLee Millward <lmillward@gcc.gnu.org>2006-10-17 23:22:14 +0000
commit72f8fc592bc86e22853d389886f326b201f7d8ac (patch)
tree6b65296bdb4fe909caa51f2ee2b16f75b74179f1 /gcc
parent4ac6f4c5e645b310acc0f9a0e22ef0e3e4fd6019 (diff)
downloadgcc-72f8fc592bc86e22853d389886f326b201f7d8ac.tar.gz
re PR c++/27952 (ICE with invalid virtual inheritance)
PR c++/27952 * cp-tree.h (xref_basetypes): Return bool instead of void. * decl.c (xref_basetypes): Adjust definition. Return false if the class bases are invalid. * parser.c (cp_parser_class_head): Check the return value from xref_basetypes. * g++.dg/inherit/virtual1.C: New test. From-SVN: r117839
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/decl.c30
-rw-r--r--gcc/cp/parser.c3
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/inherit/virtual1.C12
6 files changed, 51 insertions, 10 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 1423822480d..2358e9bf818 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,12 @@
+2006-10-17 Lee Millward <lee.millward@codesourcery.com>
+
+ PR c++/27952
+ * cp-tree.h (xref_basetypes): Return bool instead of void.
+ * decl.c (xref_basetypes): Adjust definition. Return false
+ if the class bases are invalid.
+ * parser.c (cp_parser_class_head): Check the return value
+ from xref_basetypes.
+
2006-10-17 Mark Mitchell <mark@codesourcery.com>
PR c++/28261
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 8de90605c2b..43b0202c940 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -3909,7 +3909,7 @@ extern int grok_ctor_properties (tree, tree);
extern bool grok_op_properties (tree, bool);
extern tree xref_tag (enum tag_types, tree, tag_scope, bool);
extern tree xref_tag_from_type (tree, tree, tag_scope);
-extern void xref_basetypes (tree, tree);
+extern bool xref_basetypes (tree, tree);
extern tree start_enum (tree);
extern void finish_enum (tree);
extern void build_enumerator (tree, tree, tree);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 11bb6486456..a2a650d4ef3 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -9776,9 +9776,12 @@ xref_tag_from_type (tree old, tree id, tag_scope scope)
/* Create the binfo hierarchy for REF with (possibly NULL) base list
BASE_LIST. For each element on BASE_LIST the TREE_PURPOSE is an
access_* node, and the TREE_VALUE is the type of the base-class.
- Non-NULL TREE_TYPE indicates virtual inheritance. */
+ Non-NULL TREE_TYPE indicates virtual inheritance.
+
+ Returns true if the binfo heirarchy was successfully created,
+ false if an error was detected. */
-void
+bool
xref_basetypes (tree ref, tree base_list)
{
tree *basep;
@@ -9790,7 +9793,7 @@ xref_basetypes (tree ref, tree base_list)
tree igo_prev; /* Track Inheritance Graph Order. */
if (ref == error_mark_node)
- return;
+ return false;
/* The base of a derived class is private by default, all others are
public. */
@@ -9842,13 +9845,19 @@ xref_basetypes (tree ref, tree base_list)
CLASSTYPE_NON_AGGREGATE (ref) = 1;
if (TREE_CODE (ref) == UNION_TYPE)
- error ("derived union %qT invalid", ref);
+ {
+ error ("derived union %qT invalid", ref);
+ return false;
+ }
}
if (max_bases > 1)
{
if (TYPE_FOR_JAVA (ref))
- error ("Java class %qT cannot have multiple bases", ref);
+ {
+ error ("Java class %qT cannot have multiple bases", ref);
+ return false;
+ }
}
if (max_vbases)
@@ -9856,7 +9865,10 @@ xref_basetypes (tree ref, tree base_list)
CLASSTYPE_VBASECLASSES (ref) = VEC_alloc (tree, gc, max_vbases);
if (TYPE_FOR_JAVA (ref))
- error ("Java class %qT cannot have virtual bases", ref);
+ {
+ error ("Java class %qT cannot have virtual bases", ref);
+ return false;
+ }
}
for (igo_prev = binfo; base_list; base_list = TREE_CHAIN (base_list))
@@ -9877,7 +9889,7 @@ xref_basetypes (tree ref, tree base_list)
{
error ("base type %qT fails to be a struct or class type",
basetype);
- continue;
+ return false;
}
if (TYPE_FOR_JAVA (basetype) && (current_lang_depth () == 0))
@@ -9911,7 +9923,7 @@ xref_basetypes (tree ref, tree base_list)
error ("recursive type %qT undefined", basetype);
else
error ("duplicate base type %qT invalid", basetype);
- continue;
+ return false;
}
TYPE_MARKED_P (basetype) = 1;
@@ -9954,6 +9966,8 @@ xref_basetypes (tree ref, tree base_list)
else
break;
}
+
+ return true;
}
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 90993c9bdd8..8d25db680fc 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -13499,7 +13499,8 @@ cp_parser_class_head (cp_parser* parser,
bases = cp_parser_base_clause (parser);
/* Process the base classes. */
- xref_basetypes (type, bases);
+ if (!xref_basetypes (type, bases))
+ type = NULL_TREE;
done:
/* Leave the scope given by the nested-name-specifier. We will
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 19f897b4a91..8e0c054a12d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2006-10-17 Lee Millward <lee.millward@codesuorcery.com>
+
+ PR c++/27952
+ * g++.dg/inherit/virtual1.C: New test.
+
2006-10-17 Mark Mitchell <mark@codesourcery.com>
PR c++/28261
diff --git a/gcc/testsuite/g++.dg/inherit/virtual1.C b/gcc/testsuite/g++.dg/inherit/virtual1.C
new file mode 100644
index 00000000000..08bcbb143cf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/inherit/virtual1.C
@@ -0,0 +1,12 @@
+//PR c++/27952
+
+struct A
+{
+ virtual ~A() {}
+};
+
+struct B : A, virtual A {}; // { dg-error "duplicate base|forward declaration" }
+
+struct C : A, B {}; // { dg-error "duplicate base|invalid use" }
+
+C c; // { dg-error "aggregate" }