Core issues 2273 and 2277
authorJason Merrill <jason@redhat.com>
Sat, 4 Mar 2017 08:12:28 +0000 (03:12 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Sat, 4 Mar 2017 08:12:28 +0000 (03:12 -0500)
* call.c (joust): Adjust using-declaration tiebreaker to handle
the intermediate base case.
* method.c (strip_inheriting_ctors): Just return the argument if
!flag_new_inheriting_ctors.

From-SVN: r245892

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/method.c
gcc/testsuite/g++.dg/overload/using5.C [new file with mode: 0644]

index f98726eaf5985399762679515355c5b77e6b0c72..b99a7746fb06b936ad266993337ca6206a2496a2 100644 (file)
@@ -1,3 +1,11 @@
+2017-03-03  Jason Merrill  <jason@redhat.com>
+
+       Core issues 2273 and 2277
+       * call.c (joust): Adjust using-declaration tiebreaker to handle
+       the intermediate base case.
+       * method.c (strip_inheriting_ctors): Just return the argument if
+       !flag_new_inheriting_ctors.
+
 2017-03-03  Richard Biener  <rguenther@suse.de>
 
        PR c++/79825
index dc629b96bb707a2df4b9e6e7ca7073bbbb4ff196..5afec4f0897bff140ee31e0fc40c0895193e29f7 100644 (file)
@@ -9735,20 +9735,26 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn,
        }
     }
 
-  /* or, if not that, F2 is from a using-declaration, F1 is not, and the
-     conversion sequences are equivalent.
-     (proposed in http://lists.isocpp.org/core/2016/10/1142.php) */
+  /* F1 is a member of a class D, F2 is a member of a base class B of D, and
+     for all arguments the corresponding parameters of F1 and F2 have the same
+     type (CWG 2273/2277). */
   if (DECL_P (cand1->fn) && DECL_CLASS_SCOPE_P (cand1->fn)
       && !DECL_CONV_FN_P (cand1->fn)
       && DECL_P (cand2->fn) && DECL_CLASS_SCOPE_P (cand2->fn)
       && !DECL_CONV_FN_P (cand2->fn))
     {
-      bool used1 = (DECL_INHERITED_CTOR (cand1->fn)
-                   || (BINFO_TYPE (cand1->access_path)
-                       != DECL_CONTEXT (cand1->fn)));
-      bool used2 = (DECL_INHERITED_CTOR (cand2->fn)
-                   || (BINFO_TYPE (cand2->access_path)
-                       != DECL_CONTEXT (cand2->fn)));
+      tree base1 = DECL_CONTEXT (strip_inheriting_ctors (cand1->fn));
+      tree base2 = DECL_CONTEXT (strip_inheriting_ctors (cand2->fn));
+
+      bool used1 = false;
+      bool used2 = false;
+      if (base1 == base2)
+       /* No difference.  */;
+      else if (DERIVED_FROM_P (base1, base2))
+       used1 = true;
+      else if (DERIVED_FROM_P (base2, base1))
+       used2 = true;
+
       if (int diff = used2 - used1)
        {
          for (i = 0; i < len; ++i)
index beb0a24a0b9c27f605074e02131fa7902dd82206..f6024cda28a97ffb385664372e6a638debf3ad87 100644 (file)
@@ -498,7 +498,8 @@ forward_parm (tree parm)
 tree
 strip_inheriting_ctors (tree dfn)
 {
-  gcc_assert (flag_new_inheriting_ctors);
+  if (!flag_new_inheriting_ctors)
+    return dfn;
   tree fn = dfn;
   while (tree inh = DECL_INHERITED_CTOR (fn))
     {
diff --git a/gcc/testsuite/g++.dg/overload/using5.C b/gcc/testsuite/g++.dg/overload/using5.C
new file mode 100644 (file)
index 0000000..ad17c78
--- /dev/null
@@ -0,0 +1,28 @@
+// Core issues 2273, 2277
+// { dg-do compile { target c++11 } }
+
+struct A
+{
+  A(int, int = 0);
+  static void f(int = 0);
+};
+
+struct B: A
+{
+  using A::A;
+  B(int);
+
+  using A::f;
+  static void f();
+};
+
+struct C: B {
+  using B::B;
+  using B::f;
+};
+  
+int main()
+{
+  C c (42);
+  c.f();
+}