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" }
+};

Reply via email to