]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: Allow template rvalue-ref conv to bind to lvalue ref.
authorJason Merrill <jason@redhat.com>
Tue, 28 Jan 2020 17:26:10 +0000 (12:26 -0500)
committerJason Merrill <jason@redhat.com>
Tue, 28 Jan 2020 19:56:01 +0000 (14:56 -0500)
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.

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/testsuite/g++.dg/cpp0x/rv-conv3.C [new file with mode: 0644]

index 43fcf822df9cdf16fd8588cacc2c8bb33aff0895..64ca338029ba657b941ce089b1893bf44747efd8 100644 (file)
@@ -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.
 
index 787a7ed387bd3bfdffaa3974045b8e6f4839e37b..f365a5a7f7bc3322f4dad12ef444f27cfdffd212 100644 (file)
@@ -4034,6 +4034,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 (file)
index 0000000..5f727fc
--- /dev/null
@@ -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{});
+}