This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[COMMITTED] 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.

Tested x86_64-pc-linux-gnu, applying to trunk.

	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/call.c                         |  2 ++
 gcc/testsuite/g++.dg/cpp0x/rv-conv3.C | 15 +++++++++++++++
 2 files changed, 17 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/rv-conv3.C

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 009cb85ad60..fde29f8f631 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 00000000000..5f727fcc0d5
--- /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{});
+}

base-commit: 0968f7da26221bfc9203cd557c8636c0a0f24018
-- 
2.18.1


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]