From: Mark Mitchell Date: Mon, 11 Aug 2003 02:49:44 +0000 (+0000) Subject: re PR c++/11789 (rejects legal, multiple inheritance (inheriting from same class... X-Git-Tag: releases/gcc-3.4.0~4307 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d9148cf498826028803b6e00a2ca60ac83113cfb;p=thirdparty%2Fgcc.git re PR c++/11789 (rejects legal, multiple inheritance (inheriting from same class twice)) PR c++/11789 * cp-tree.h (get_vbase): Remove. (get_vbase_types): Remove. * init.c (expand_member_init): Correct logic for looking up base classes. PR c++/11789.C * g++.dg/inherit/multiple1.C: New test. From-SVN: r70316 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index fde090e1bb72..191879fe25f6 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2003-08-10 Mark Mitchell + + PR c++/11789 + * cp-tree.h (get_vbase): Remove. + (get_vbase_types): Remove. + * init.c (expand_member_init): Correct logic for looking up base + classes. + 2003-08-10 Gabriel Dos Reis * error.c (dump_expr): Tidy. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index d47c3077d093..a740142c1efc 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4018,7 +4018,6 @@ extern bool emit_tinfo_decl (tree); extern bool accessible_base_p (tree, tree); extern tree lookup_base (tree, tree, base_access, base_kind *); extern int types_overlap_p (tree, tree); -extern tree get_vbase (tree, tree); extern tree get_dynamic_cast_base_type (tree, tree); extern int accessible_p (tree, tree); extern tree lookup_field_1 (tree, tree, bool); @@ -4028,7 +4027,6 @@ extern tree lookup_fnfields (tree, tree, int); extern tree lookup_member (tree, tree, int, bool); extern int look_for_overrides (tree, tree); extern void get_pure_virtuals (tree); -extern void get_vbase_types (tree); extern void maybe_suppress_debug_info (tree); extern void note_debug_info_needed (tree); extern void push_class_decls (tree); diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 1774af4ae30d..95824516c8a6 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -963,16 +963,50 @@ expand_member_init (tree name) if (basetype) { - tree binfo; + tree class_binfo; + tree direct_binfo; + tree virtual_binfo; + int i; if (current_template_parms) return basetype; - binfo = lookup_base (current_class_type, basetype, - ba_ignore, NULL); - if (!binfo || (!TREE_VIA_VIRTUAL (binfo) - && (BINFO_INHERITANCE_CHAIN (binfo) - != TYPE_BINFO (current_class_type)))) + class_binfo = TYPE_BINFO (current_class_type); + direct_binfo = NULL_TREE; + virtual_binfo = NULL_TREE; + + /* Look for a direct base. */ + for (i = 0; i < BINFO_N_BASETYPES (class_binfo); ++i) + if (same_type_p (basetype, + TYPE_BINFO_BASETYPE (current_class_type, i))) + { + direct_binfo = BINFO_BASETYPE (class_binfo, i); + break; + } + /* Look for a virtual base -- unless the direct base is itself + virtual. */ + if (!direct_binfo || !TREE_VIA_VIRTUAL (direct_binfo)) + { + virtual_binfo + = purpose_member (basetype, + CLASSTYPE_VBASECLASSES (current_class_type)); + if (virtual_binfo) + virtual_binfo = TREE_VALUE (virtual_binfo); + } + + /* [class.base.init] + + If a mem-initializer-id is ambiguous because it designates + both a direct non-virtual base class and an inherited virtual + base class, the mem-initializer is ill-formed. */ + if (direct_binfo && virtual_binfo) + { + error ("'%D' is both a direct base and an indirect virtual base", + basetype); + return NULL_TREE; + } + + if (!direct_binfo && !virtual_binfo) { if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type)) error ("type `%D' is not a direct or virtual base of `%T'", @@ -982,7 +1016,8 @@ expand_member_init (tree name) name, current_class_type); return NULL_TREE; } - return binfo; + + return direct_binfo ? direct_binfo : virtual_binfo; } else { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0c82d526ba5c..9580129a8b58 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2003-08-10 Mark Mitchell + + PR c++/11789.C + * g++.dg/inherit/multiple1.C: New test. + 2003-08-10 Nathan Sidwell * gcc.dg/spe1.c: New test. diff --git a/gcc/testsuite/g++.dg/inherit/multiple1.C b/gcc/testsuite/g++.dg/inherit/multiple1.C new file mode 100644 index 000000000000..3eb9fe763a7c --- /dev/null +++ b/gcc/testsuite/g++.dg/inherit/multiple1.C @@ -0,0 +1,20 @@ +// { dg-options "-w" } + +struct Base { + int b; + + Base(int b) : b(b) { } +}; + +struct Derived : public Base { + Derived(int d) : Base(d) { } +}; + +struct Final : public Derived, public Base { + Final(int f) : Derived(f), Base(f-1) { } +}; + +int main() +{ + Final f(5); +}