aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@codesourcery.com>2001-12-04 09:48:53 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2001-12-04 09:48:53 +0000
commit713ccd0c6c230f7680c9d4c9502f5daab7002a26 (patch)
treef877292b1f2f08518c8e2c8a040ed40556594a36
parentb318748ff4b6a9256695a3e768d4a951dd4b8ca6 (diff)
downloadgcc-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
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/init.c3
-rw-r--r--gcc/cp/method.c41
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.dg/inherit/base1.C22
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;
+}