Here build_base_path expects that the binfo argument will designate a
subobject of the expression argument, but that isn't the case here
because the base is ambiguous. So let's complain about that instead of
aborting.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit 640c9c1f2824490323a8deb32170379ffeb2c399
Author: Jason Merrill <ja...@redhat.com>
Date: Tue Jan 10 14:45:48 2012 -0500
PR c++/51614
* class.c (build_base_path): Diagnose ambiguous base.
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 79686a2..58c89d3 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -266,10 +266,25 @@ build_base_path (enum tree_code code,
if (want_pointer)
probe = TYPE_MAIN_VARIANT (TREE_TYPE (probe));
+ if (code == PLUS_EXPR
+ && !SAME_BINFO_TYPE_P (BINFO_TYPE (d_binfo), probe))
+ {
+ /* This can happen when adjust_result_of_qualified_name_lookup can't
+ find a unique base binfo in a call to a member function. We
+ couldn't give the diagnostic then since we might have been calling
+ a static member function, so we do it now. */
+ if (complain & tf_error)
+ {
+ tree base = lookup_base (probe, BINFO_TYPE (d_binfo),
+ ba_unique, NULL);
+ gcc_assert (base == error_mark_node);
+ }
+ return error_mark_node;
+ }
+
gcc_assert ((code == MINUS_EXPR
&& SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), probe))
- || (code == PLUS_EXPR
- && SAME_BINFO_TYPE_P (BINFO_TYPE (d_binfo), probe)));
+ || code == PLUS_EXPR);
if (binfo == d_binfo)
/* Nothing to do. */
diff --git a/gcc/testsuite/g++.dg/inherit/ambig1.C b/gcc/testsuite/g++.dg/inherit/ambig1.C
new file mode 100644
index 0000000..3596bb5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/inherit/ambig1.C
@@ -0,0 +1,14 @@
+// PR c++/51614
+
+struct A
+{
+ void foo();
+};
+
+struct B : A {};
+struct C : A {};
+
+struct D : B, C
+{
+ D() { A::foo(); } // { dg-error "ambiguous" }
+};