Index: gcc/testsuite/g++.dg/inherit/virtual1.C =================================================================== --- gcc/testsuite/g++.dg/inherit/virtual1.C (revision 0) +++ gcc/testsuite/g++.dg/inherit/virtual1.C (revision 0) @@ -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" } Index: gcc/cp/decl.c =================================================================== --- gcc/cp/decl.c (revision 117730) +++ gcc/cp/decl.c (working copy) @@ -9779,9 +9779,12 @@ xref_tag_from_type (tree old, tree id, t /* 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; @@ -9793,7 +9796,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. */ @@ -9845,13 +9848,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) @@ -9859,7 +9868,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)) @@ -9880,7 +9892,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)) @@ -9914,7 +9926,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; @@ -9957,6 +9969,8 @@ xref_basetypes (tree ref, tree base_list else break; } + + return true; } Index: gcc/cp/cp-tree.h =================================================================== --- gcc/cp/cp-tree.h (revision 117730) +++ gcc/cp/cp-tree.h (working copy) @@ -3909,7 +3909,7 @@ extern int grok_ctor_properties (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); Index: gcc/cp/parser.c =================================================================== --- gcc/cp/parser.c (revision 117730) +++ gcc/cp/parser.c (working copy) @@ -13440,7 +13440,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