Patchwork C++ PATCH for c++/57064 (ref-qualifier and function returning rvalue ref)

login
register
mail settings
Submitter Jason Merrill
Date April 25, 2013, 4:22 p.m.
Message ID <51795835.2060601@redhat.com>
Download mbox | patch
Permalink /patch/239562/
State New
Headers show

Comments

Jason Merrill - April 25, 2013, 4:22 p.m.
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.

Patch

commit 5742904a95f4daaa0752bea6e1599e82197419b0
Author: Jason Merrill <jason@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();
+}