From 02510aca9a164f736c2e4bc5a0defdd168314064 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Wed, 26 Apr 2017 10:14:15 -0400
Subject: [PATCH 10/10] FIXME: WIP on improvements to 'ambiguous base' C++ diag

---
 gcc/cp/search.c                                    | 82 +++++++++++++++++++++-
 gcc/testsuite/g++.dg/template/show-template-tree.C |  8 +++
 2 files changed, 89 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index 09c1b4e..e6f0908 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -28,6 +28,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "intl.h"
 #include "toplev.h"
 #include "spellcheck-tree.h"
+#include "print-tree.h"
 
 static int is_subobject_of_p (tree, tree);
 static tree dfs_lookup_base (tree, void *);
@@ -130,6 +131,70 @@ dfs_lookup_base (tree binfo, void *data_)
   return NULL_TREE;
 }
 
+// FIXME
+
+static tree
+dfs_report_ambiguous_base (tree binfo, void *data_)
+{
+  struct lookup_base_data_s *data = (struct lookup_base_data_s *) data_;
+
+  debug (binfo);
+  debug_tree (binfo);
+
+  if (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), data->base))
+    {
+      fprintf (stderr, "SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), data->base)\n");
+      //debug (binfo);
+      //return binfo;
+#if 0
+      if (!data->binfo)
+	{
+	  data->binfo = binfo;
+	  data->via_virtual
+	    = binfo_via_virtual (data->binfo, data->t) != NULL_TREE;
+
+	  if (!data->repeated_base)
+	    /* If there are no repeated bases, we can stop now.  */
+	    return binfo;
+
+	  if (data->want_any && !data->via_virtual)
+	    /* If this is a non-virtual base, then we can't do
+	       better.  */
+	    return binfo;
+
+	  return dfs_skip_bases;
+	}
+      else
+	{
+	  gcc_assert (binfo != data->binfo);
+
+	  /* We've found more than one matching binfo.  */
+	  if (!data->want_any)
+	    {
+	      /* This is immediately ambiguous.  */
+	      data->binfo = NULL_TREE;
+	      data->ambiguous = true;
+	      return error_mark_node;
+	    }
+
+	  /* Prefer one via a non-virtual path.  */
+	  if (!binfo_via_virtual (binfo, data->t))
+	    {
+	      data->binfo = binfo;
+	      data->via_virtual = false;
+	      return binfo;
+	    }
+
+	  /* There must be repeated bases, otherwise we'd have stopped
+	     on the first base we found.  */
+	  return dfs_skip_bases;
+	}
+#endif
+    }
+
+  return NULL_TREE;
+}
+
 /* Returns true if type BASE is accessible in T.  (BASE is known to be
    a (possibly non-proper) base class of T.)  If CONSIDER_LOCAL_P is
    true, consider any special access of the current scope, or access
@@ -245,7 +310,22 @@ lookup_base (tree t, tree base, base_access access,
 
       case bk_ambig:
 	if (complain & tf_error)
-	  error ("%qT is an ambiguous base of %qT", base, t);
+	  {
+	    error ("%qT is an ambiguous base of %qT", base, t);
+	    inform (input_location, "new stuff goes here");
+	    /* This is a copy-and-paste of the stuff above,
+	       but we want to capture all, probably.  */
+	    struct lookup_base_data_s data;
+
+	    data.t = t;
+	    data.base = base;
+	    data.binfo = NULL_TREE;
+	    data.ambiguous = data.via_virtual = false;
+	    data.repeated_base = CLASSTYPE_REPEATED_BASE_P (t);
+	    data.want_any = access == ba_any;
+
+	    dfs_walk_once (t_binfo, dfs_report_ambiguous_base, NULL, &data);
+	  }
 	binfo = error_mark_node;
 	break;
 
diff --git a/gcc/testsuite/g++.dg/template/show-template-tree.C b/gcc/testsuite/g++.dg/template/show-template-tree.C
index 9737db6..f68dd1f 100644
--- a/gcc/testsuite/g++.dg/template/show-template-tree.C
+++ b/gcc/testsuite/g++.dg/template/show-template-tree.C
@@ -6,9 +6,12 @@ template<typename, typename> struct map {};
 void fn_1(vector<int>);
 void fn_2(map<int, int>);
 void fn_3(vector<map<int, float> >);
+void fn_4(vector<map<int, float> >&);
+void fn_5(vector<map<int, float> >*);
 
 void test ()
 {
+#if 0
   fn_1 (vector<int> ());
   fn_1 (42); // { dg-error "could not convert '42' from 'int' to 'vector<int>'" }
   fn_1 (vector<double> ()); // { dg-error "could not convert 'vector<double>\\(\\)' from 'vector<double>' to 'vector<int>'" }
@@ -40,4 +43,9 @@ void test ()
       [...],
       [double != float]>>
      { dg-end-multiline-output "" } */
+#endif
+
+  vector<map<int, double> > v;
+  //fn_4 (v);
+  fn_5 (&v);
 }
-- 
1.8.5.3

