[gcc(refs/vendors/axis/heads/cris-decc0)] c++: Allow template rvalue-ref conv to bind to lvalue ref.

Hans-Peter Nilsson hp@gcc.gnu.org
Wed Feb 12 06:10:00 GMT 2020


https://gcc.gnu.org/g:14e320dbc10cc796fd7ca0b6c44e0c9ac0901da9

commit 14e320dbc10cc796fd7ca0b6c44e0c9ac0901da9
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Jan 28 12:26:10 2020 -0500

    c++: Allow template rvalue-ref conv to bind to lvalue ref.
    
    When I implemented the [over.match.ref] rule that a reference conversion
    function needs to match l/rvalue of the target reference type it changed our
    handling of this testcase.  It seems to me that our current behavior is what
    the standard says, but it doesn't seem desirable, and all the other
    compilers have our old behavior.  So let's limit the change to non-templates
    until there's some clarification from the committee.
    
    	PR c++/90546
    	* call.c (build_user_type_conversion_1): Allow a template conversion
    	returning an rvalue reference to bind directly to an lvalue.

Diff:
---
 gcc/cp/ChangeLog                      |  4 ++++
 gcc/cp/call.c                         |  2 ++
 gcc/testsuite/g++.dg/cpp0x/rv-conv3.C | 15 +++++++++++++++
 3 files changed, 21 insertions(+)

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 259b0c7..a110efe 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,9 @@
 2020-01-28  Jason Merrill  <jason@redhat.com>
 
+	PR c++/90546
+	* call.c (build_user_type_conversion_1): Allow a template conversion
+	returning an rvalue reference to bind directly to an lvalue.
+
 	PR c++/90731
 	* decl.c (grokdeclarator): Propagate eh spec from typedef.
 
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 009cb85..fde29f8 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -4115,6 +4115,8 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags,
 						       EXPR_LOCATION (expr));
 	    }
 	  else if (TYPE_REF_P (totype) && !ics->rvaluedness_matches_p
+		   /* Limit this to non-templates for now (PR90546).  */
+		   && !cand->template_decl
 		   && TREE_CODE (TREE_TYPE (totype)) != FUNCTION_TYPE)
 	    {
 	      /* If we are called to convert to a reference type, we are trying
diff --git a/gcc/testsuite/g++.dg/cpp0x/rv-conv3.C b/gcc/testsuite/g++.dg/cpp0x/rv-conv3.C
new file mode 100644
index 0000000..5f727fc
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/rv-conv3.C
@@ -0,0 +1,15 @@
+// PR c++/90546
+// { dg-do link { target c++11 } }
+
+struct Foo { };
+void test(const Foo&) {}
+Foo f;
+struct Bar {
+  template <class T> operator T&&();
+};
+template<> Bar::operator const Foo&&() {
+    return static_cast<Foo&&>(f);
+}
+int main() {
+  test(Bar{});
+}



More information about the Gcc-cvs mailing list