diff options
author | Nathan Sidwell <nathan@codesourcery.com> | 2001-12-04 09:48:53 +0000 |
---|---|---|
committer | Nathan Sidwell <nathan@gcc.gnu.org> | 2001-12-04 09:48:53 +0000 |
commit | 713ccd0c6c230f7680c9d4c9502f5daab7002a26 (patch) | |
tree | f877292b1f2f08518c8e2c8a040ed40556594a36 /gcc | |
parent | b318748ff4b6a9256695a3e768d4a951dd4b8ca6 (diff) | |
download | gcc-713ccd0c6c230f7680c9d4c9502f5daab7002a26.zip gcc-713ccd0c6c230f7680c9d4c9502f5daab7002a26.tar.gz gcc-713ccd0c6c230f7680c9d4c9502f5daab7002a26.tar.bz2 |
re PR c++/164 (bogus error throwing class with inaccessible base)
cp:
PR g++/164
* init.c (sort_base_init): Allow binfos to be directly specified.
* method.c (do_build_copy_constructor): Explicitly convert to the
base instance.
(do_build_assign_ref): Likewise.
testsuite:
* g++.dg/inherit/base1.C: New test.
From-SVN: r47603
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/init.c | 3 | ||||
-rw-r--r-- | gcc/cp/method.c | 41 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/inherit/base1.C | 22 |
5 files changed, 63 insertions, 15 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c2abaab..d869b0d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2001-12-04 Nathan Sidwell <nathan@codesourcery.com> + + PR g++/164 + * init.c (sort_base_init): Allow binfos to be directly specified. + * method.c (do_build_copy_constructor): Explicitly convert to the + base instance. + (do_build_assign_ref): Likewise. + 2001-12-03 Hans-Peter Nilsson <hp@bitrange.com> * decl.c (xref_basetypes): Don't use C99 construct in tag_code diff --git a/gcc/cp/init.c b/gcc/cp/init.c index b7b230d..169bc8c 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -556,7 +556,8 @@ sort_base_init (t, base_init_list, rbase_ptr, vbase_ptr) for (x = TREE_CHAIN (last); x; x = TREE_CHAIN (x)) { tree basetype = TREE_PURPOSE (x); - tree binfo = binfo_or_else (basetype, t); + tree binfo = (TREE_CODE (basetype) == TREE_VEC + ? basetype : binfo_or_else (basetype, t)); if (binfo == NULL_TREE) /* BASETYPE might be an inaccessible direct base (because it diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 4de7605..2424623 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -554,25 +554,31 @@ do_build_copy_constructor (fndecl) int cvquals = cp_type_quals (TREE_TYPE (parm)); int i; - /* Initialize all the base-classes with the parameter converted to - their type so that we get their copy constructor and not another - constructor that takes current_class_type. */ + /* Initialize all the base-classes with the parameter converted + to their type so that we get their copy constructor and not + another constructor that takes current_class_type. We must + deal with the binfo's directly as a direct base might be + inaccessible due to ambiguity. */ for (t = CLASSTYPE_VBASECLASSES (current_class_type); t; t = TREE_CHAIN (t)) { - tree type = BINFO_TYPE (TREE_VALUE (t)); - base_init_list = tree_cons (type, convert_lvalue (type, parm), + tree binfo = TREE_VALUE (t); + + base_init_list = tree_cons (binfo, + build_base_path (PLUS_EXPR, parm, + binfo, 1), base_init_list); } for (i = 0; i < n_bases; ++i) { - t = TREE_VEC_ELT (binfos, i); - if (TREE_VIA_VIRTUAL (t)) + tree binfo = TREE_VEC_ELT (binfos, i); + if (TREE_VIA_VIRTUAL (binfo)) continue; - t = BINFO_TYPE (t); - base_init_list = tree_cons (t, convert_lvalue (t, parm), + base_init_list = tree_cons (binfo, + build_base_path (PLUS_EXPR, parm, + binfo, 1), base_init_list); } @@ -645,11 +651,18 @@ do_build_assign_ref (fndecl) for (i = 0; i < n_bases; ++i) { - tree basetype = BINFO_TYPE (TREE_VEC_ELT (binfos, i)); - tree p = convert_lvalue (basetype, parm); - p = build_member_call (basetype, ansi_assopname (NOP_EXPR), - build_tree_list (NULL_TREE, p)); - finish_expr_stmt (p); + /* We must deal with the binfo's directly as a direct base + might be inaccessible due to ambiguity. */ + tree binfo = TREE_VEC_ELT (binfos, i); + tree src = build_base_path (PLUS_EXPR, parm, binfo, 1); + tree dst = build_base_path (PLUS_EXPR, current_class_ref, binfo, 1); + + tree expr = build_method_call (dst, + ansi_assopname (NOP_EXPR), + build_tree_list (NULL_TREE, src), + NULL, + LOOKUP_NORMAL | LOOKUP_NONVIRTUAL); + finish_expr_stmt (expr); } for (; fields; fields = TREE_CHAIN (fields)) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 76f673f..795c502 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2001-12-04 Nathan Sidwell <nathan@codesourcery.com> + + * g++.dg/inherit/base1.C: New test. + 2001-12-04 Jakub Jelinek <jakub@redhat.com> * g++.dg/other/stdarg1.C: New test. diff --git a/gcc/testsuite/g++.dg/inherit/base1.C b/gcc/testsuite/g++.dg/inherit/base1.C new file mode 100644 index 0000000..952c6d2 --- /dev/null +++ b/gcc/testsuite/g++.dg/inherit/base1.C @@ -0,0 +1,22 @@ +// { dg-do compile } +// { dg-options "-pedantic-errors -w" } + +// Copyright (C) 2000 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 29 Nov 2001 <nathan@nathan@codesourcery.com> + +// PR 164 +// Although a direct base can be inaccessible due to ambiguity, that +// should not blow up synthesized methods. + +struct A {int m;}; +struct B : A {int m;}; +struct C : virtual A, B {int m;}; +struct D : B, C {int m;}; + +void foo2 () +{ + D d; + D e (d); + + e = d; +} |