Our implementation of the CWG 2273 inheritedness tiebreaker seems to be
incorrectly considering all inherited members, not just inherited
constructors.  This patch restricts the tiebreaker accordingly.

        DR 2273

gcc/cp/ChangeLog:

        * call.cc (joust): Restrict inheritedness tiebreaker to
        constructors.

gcc/testsuite/ChangeLog:

        * g++.dg/cpp1z/using1.C: Expect ambiguity for non-constructor call.
        * g++.dg/overload/using5.C: Likewise.
---
 gcc/cp/call.cc                         | 12 +++++-------
 gcc/testsuite/g++.dg/cpp1z/using1.C    |  7 +++----
 gcc/testsuite/g++.dg/overload/using5.C |  2 +-
 3 files changed, 9 insertions(+), 12 deletions(-)

diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index 3f753e2d2f9..87b54291b51 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -13350,13 +13350,11 @@ joust (struct z_candidate *cand1, struct z_candidate 
*cand2, bool warn,
        }
     }
 
-  /* 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))
+  /* F1 is a constructor for a class D, F2 is a constructor for 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_CONSTRUCTOR_P (cand1->fn)
+      && DECL_P (cand2->fn) && DECL_CONSTRUCTOR_P (cand2->fn))
     {
       tree base1 = DECL_CONTEXT (strip_inheriting_ctors (cand1->fn));
       tree base2 = DECL_CONTEXT (strip_inheriting_ctors (cand2->fn));
diff --git a/gcc/testsuite/g++.dg/cpp1z/using1.C 
b/gcc/testsuite/g++.dg/cpp1z/using1.C
index 1ed939d45fd..c7278ec880a 100644
--- a/gcc/testsuite/g++.dg/cpp1z/using1.C
+++ b/gcc/testsuite/g++.dg/cpp1z/using1.C
@@ -1,5 +1,4 @@
-// Test for hiding of used base functions when all the conversion sequences are
-// equivalent, needed to avoid a regression on inherited default ctors.
+// Test the CWG 2237 resolution doesn't apply to inherited non-constructors.
 
 struct A
 {
@@ -17,7 +16,7 @@ struct B:A
 
 int main()
 {
-  B().f(1);                    // OK, derived f hides base f for single arg
+  B().f(1);                    // { dg-error "ambiguous" }
   B().f(1,2);                  // OK, base f can still be called with two args
-  B().g(1);                    // { dg-error "" } signatures differ, ambiguous
+  B().g(1);                    // { dg-error "ambiguous" } signatures differ
 }
diff --git a/gcc/testsuite/g++.dg/overload/using5.C 
b/gcc/testsuite/g++.dg/overload/using5.C
index ad17c78a561..0933a9f0fac 100644
--- a/gcc/testsuite/g++.dg/overload/using5.C
+++ b/gcc/testsuite/g++.dg/overload/using5.C
@@ -24,5 +24,5 @@ struct C: B {
 int main()
 {
   C c (42);
-  c.f();
+  c.f(); // { dg-error "ambiguous" }
 }
-- 
2.46.1.544.g3fb745257b

Reply via email to