aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2011-03-16 16:15:37 -0400
committerJason Merrill <jason@gcc.gnu.org>2011-03-16 16:15:37 -0400
commit532c679ea9bdf337fa0c09cbc9b0737b4a4b1aa9 (patch)
tree66c253d5d159933f9c7c3b6e5800ded9fa34c036 /gcc
parente676810ed18f44d6b183f7608b3d68b1c5284897 (diff)
downloadgcc-532c679ea9bdf337fa0c09cbc9b0737b4a4b1aa9.zip
gcc-532c679ea9bdf337fa0c09cbc9b0737b4a4b1aa9.tar.gz
gcc-532c679ea9bdf337fa0c09cbc9b0737b4a4b1aa9.tar.bz2
Core 1148
Core 1148 * typeck.c (check_return_expr): Fix conditions for setting LOOKUP_PREFER_RVALUE. From-SVN: r171071
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/typeck.c19
-rw-r--r--gcc/testsuite/ChangeLog2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/elision2.C13
4 files changed, 32 insertions, 6 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 35d0337..fe16983 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,9 @@
2011-03-16 Jason Merrill <jason@redhat.com>
+ Core 1148
+ * typeck.c (check_return_expr): Fix conditions for setting
+ LOOKUP_PREFER_RVALUE.
+
* call.c (build_over_call): Remove require_complete_type_sfinae call.
PR c++/48132
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/ChangeLog b/gcc/testsuite/ChangeLog
index f5e7580..5685b45 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,7 @@
2011-03-16 Jason Merrill <jason@redhat.com>
+ * g++.dg/cpp0x/elision2.C: New.
+
* g++.dg/cpp0x/constexpr-array3.C: New.
2011-03-16 Jason Merrill <jason@redhat.com>
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;
+}