In the patch adding ref-qualifiers, I initially turned the 'this' argument back into a glvalue for the object with build_fold_indirect_ref. I was nervous about this being able to reliably reconstruct the original glvalue argument, so on the trunk I switched things to wait and take the address later. But that seemed risky for the branch, since it would affect the C++98 code path, so I left it off. This PR demonstrates that my initial nervousness was justified, so I've added a bit more code on the branch to handle this case.

Tested x86_64-pc-linux-gnu, applying to 4.8.
commit 5742904a95f4daaa0752bea6e1599e82197419b0
Author: Jason Merrill <ja...@redhat.com>
Date:   Thu Apr 25 10:38:47 2013 -0400

    	PR c++/57064
    	* call.c (add_function_candidate): Strip ref-to-ptr conversion.

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index f575dae..72c1dac 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -1959,6 +1959,10 @@ add_function_candidate (struct z_candidate **candidates,
 		     object parameter has reference type.  */
 		  bool rv = FUNCTION_RVALUE_QUALIFIED (TREE_TYPE (fn));
 		  parmtype = cp_build_reference_type (parmtype, rv);
+		  if (TREE_CODE (arg) == CONVERT_EXPR
+		      && TYPE_PTR_P (TREE_TYPE (arg)))
+		    /* Strip conversion from reference to pointer.  */
+		    arg = TREE_OPERAND (arg, 0);
 		  arg = build_fold_indirect_ref (arg);
 		  argtype = lvalue_type (arg);
 		}
diff --git a/gcc/testsuite/g++.dg/cpp0x/ref-qual9.C b/gcc/testsuite/g++.dg/cpp0x/ref-qual9.C
new file mode 100644
index 0000000..cdb8d68
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/ref-qual9.C
@@ -0,0 +1,14 @@
+// PR c++/57064
+// { dg-require-effective-target c++11 }
+
+template <class T> T&& move(T& t);
+
+struct A {
+  void p() &;
+  int p() &&;
+};
+
+void g(A &&a)
+{
+  int i = move(a).p();
+}

Reply via email to