From 6cb1ef51438f731064431977ca56f7db598409d1 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 26 Sep 2011 13:55:04 -0400 Subject: [PATCH] re PR c++/50512 (surprising change in overloading resolution) PR c++/50512 * call.c (compare_ics): Only consider rvaluedness_matches_p if the target type is the same or it too differs in rvalueness. From-SVN: r179208 --- gcc/cp/ChangeLog | 4 ++++ gcc/cp/call.c | 23 +++++++++++++++-------- gcc/testsuite/ChangeLog | 3 +++ gcc/testsuite/g++.dg/overload/rvalue3.C | 8 ++++++++ 4 files changed, 30 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/g++.dg/overload/rvalue3.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 865d76461e1..d1c79469a39 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2011-09-26 Jason Merrill + PR c++/50512 + * call.c (compare_ics): Only consider rvaluedness_matches_p + if the target type is the same or it too differs in rvalueness. + PR c++/50523 * call.c (implicit_conversion): Mask out inappropriate LOOKUP flags at the top of the function. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 579e563ea1c..a52ec29eb66 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -7864,18 +7864,25 @@ compare_ics (conversion *ics1, conversion *ics2) types to which the references refer are the same type except for top-level cv-qualifiers, and the type to which the reference initialized by S2 refers is more cv-qualified than the type to - which the reference initialized by S1 refers */ + which the reference initialized by S1 refers. + + DR 1328 [over.match.best]: the context is an initialization by + conversion function for direct reference binding (13.3.1.6) of a + reference to function type, the return type of F1 is the same kind of + reference (i.e. lvalue or rvalue) as the reference being initialized, + and the return type of F2 is not. */ if (ref_conv1 && ref_conv2) { - if (!ref_conv1->this_p && !ref_conv2->this_p) + if (!ref_conv1->this_p && !ref_conv2->this_p + && (ref_conv1->rvaluedness_matches_p + != ref_conv2->rvaluedness_matches_p) + && (same_type_p (ref_conv1->type, ref_conv2->type) + || (TYPE_REF_IS_RVALUE (ref_conv1->type) + != TYPE_REF_IS_RVALUE (ref_conv2->type)))) { - if (ref_conv1->rvaluedness_matches_p - > ref_conv2->rvaluedness_matches_p) - return 1; - if (ref_conv2->rvaluedness_matches_p - > ref_conv1->rvaluedness_matches_p) - return -1; + return (ref_conv1->rvaluedness_matches_p + - ref_conv2->rvaluedness_matches_p); } if (same_type_ignoring_top_level_qualifiers_p (to_type1, to_type2)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 500fbf577ee..56233c0a64a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2011-09-26 Jason Merrill + PR c++/50512 + * g++.dg/overload/rvalue3.C: New. + PR c++/50523 * g++.dg/overload/ref-conv2.C: New. diff --git a/gcc/testsuite/g++.dg/overload/rvalue3.C b/gcc/testsuite/g++.dg/overload/rvalue3.C new file mode 100644 index 00000000000..5a5d2374290 --- /dev/null +++ b/gcc/testsuite/g++.dg/overload/rvalue3.C @@ -0,0 +1,8 @@ +// PR c++/50512 + +void foo (const char *const& s); +template void foo (const C& x) { x.a; } + +void f () { + foo ("abc"); +}