Patchwork C++ PATCH for c++/51614 (ICE with ambiguous base)

login
register
mail settings
Submitter Jason Merrill
Date Jan. 11, 2012, 3:09 a.m.
Message ID <4F0CFD7F.9030301@redhat.com>
Download mbox | patch
Permalink /patch/135349/
State New
Headers show

Comments

Jason Merrill - Jan. 11, 2012, 3:09 a.m.
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.

Patch

commit 640c9c1f2824490323a8deb32170379ffeb2c399
Author: Jason Merrill <jason@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" }
+};