From 4cdeb2343a2203ee64c7d13ff5b36187f727b0b4 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Sat, 4 Mar 2017 03:12:28 -0500 Subject: [PATCH] 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. From-SVN: r245892 --- gcc/cp/ChangeLog | 8 ++++++++ gcc/cp/call.c | 24 +++++++++++++--------- gcc/cp/method.c | 3 ++- gcc/testsuite/g++.dg/overload/using5.C | 28 ++++++++++++++++++++++++++ 4 files changed, 53 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/g++.dg/overload/using5.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f98726eaf59..b99a7746fb0 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2017-03-03 Jason Merrill + + 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 PR c++/79825 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index dc629b96bb7..5afec4f0897 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -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) diff --git a/gcc/cp/method.c b/gcc/cp/method.c index beb0a24a0b9..f6024cda28a 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -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 index 00000000000..ad17c78a561 --- /dev/null +++ b/gcc/testsuite/g++.dg/overload/using5.C @@ -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(); +} -- 2.30.2