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]

C++ PATCH for core 1148 (move on return of function parameter)


The resolution of core issue 1148 clarifies that even though it isn't safe to elide the copy from a function parameter to its return value, we can change it to a move.

Tested x86_64-pc-linux-gnu, applied to trunk.
commit 3122c2fd2d08a4ac78c2954dda8330e59295e23f
Author: Jason Merrill <jason@redhat.com>
Date:   Wed Mar 16 15:42:13 2011 -0400

    	Core 1148
    	* typeck.c (check_return_expr): Fix conditions for setting
    	LOOKUP_PREFER_RVALUE.

diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 0e8a6d7..03aa49e 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -7760,12 +7760,19 @@ check_return_expr (tree retval, bool *no_warning)
 
       /* Under C++0x [12.8/16 class.copy], a returned lvalue is sometimes
 	 treated as an rvalue for the purposes of overload resolution to
-	 favor move constructors over copy constructors.  */
-      if ((cxx_dialect != cxx98) 
-          && named_return_value_okay_p
-          /* The variable must not have the `volatile' qualifier.  */
-	  && !CP_TYPE_VOLATILE_P (TREE_TYPE (retval))
-	  /* The return type must be a class type.  */
+	 favor move constructors over copy constructors.
+
+         Note that these conditions are similar to, but not as strict as,
+	 the conditions for the named return value optimization.  */
+      if ((cxx_dialect != cxx98)
+          && (TREE_CODE (retval) == VAR_DECL
+	      || TREE_CODE (retval) == PARM_DECL)
+	  && DECL_CONTEXT (retval) == current_function_decl
+	  && !TREE_STATIC (retval)
+	  && same_type_p ((TYPE_MAIN_VARIANT (TREE_TYPE (retval))),
+			  (TYPE_MAIN_VARIANT
+			   (TREE_TYPE (TREE_TYPE (current_function_decl)))))
+	  /* This is only interesting for class type.  */
 	  && CLASS_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))))
 	flags = flags | LOOKUP_PREFER_RVALUE;
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/elision2.C b/gcc/testsuite/g++.dg/cpp0x/elision2.C
new file mode 100644
index 0000000..216b1b5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/elision2.C
@@ -0,0 +1,13 @@
+// Core 1148: should be able to move from value parameter on return
+// { dg-options -std=c++0x }
+
+struct A
+{
+  A(const A&) = delete;
+  A(A&&);
+};
+
+A f (A a)
+{
+  return a;
+}

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