aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2013-07-09 13:56:32 -0400
committerJason Merrill <jason@gcc.gnu.org>2013-07-09 13:56:32 -0400
commitf9f91ddcf76a01b80f8b194f7402aedc40e8af79 (patch)
treef12f394846d5adb152f02632c0a0a1c532e5055d
parent9a3970ddfc50ed831d621c77a0b2157700302fa8 (diff)
downloadgcc-f9f91ddcf76a01b80f8b194f7402aedc40e8af79.zip
gcc-f9f91ddcf76a01b80f8b194f7402aedc40e8af79.tar.gz
gcc-f9f91ddcf76a01b80f8b194f7402aedc40e8af79.tar.bz2
re PR c++/57437 (C++11: mutable lambdas)
PR c++/57437 * typeck.c (check_return_expr): Lambda proxies aren't eligible for nrv or return by move. From-SVN: r200843
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/typeck.c5
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-return1.C26
3 files changed, 33 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 2d6fa73..68c6a09 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,9 @@
2013-07-09 Jason Merrill <jason@redhat.com>
+ PR c++/57437
+ * typeck.c (check_return_expr): Lambda proxies aren't eligible
+ for nrv or return by move.
+
PR c++/57532
* parser.c (cp_parser_ref_qualifier_opt): Don't tentatively parse
a ref-qualifier in C++98 mode.
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 462abdd..6f7d489 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -8399,7 +8399,8 @@ check_return_expr (tree retval, bool *no_warning)
&& VAR_P (retval)
&& DECL_CONTEXT (retval) == current_function_decl
&& ! TREE_STATIC (retval)
- && ! DECL_ANON_UNION_VAR_P (retval)
+ /* And not a lambda or anonymous union proxy. */
+ && !DECL_HAS_VALUE_EXPR_P (retval)
&& (DECL_ALIGN (retval) <= DECL_ALIGN (result))
/* The cv-unqualified type of the returned value must be the
same as the cv-unqualified return type of the
@@ -8444,7 +8445,7 @@ check_return_expr (tree retval, bool *no_warning)
Note that these conditions are similar to, but not as strict as,
the conditions for the named return value optimization. */
if ((cxx_dialect != cxx98)
- && (VAR_P (retval)
+ && ((VAR_P (retval) && !DECL_HAS_VALUE_EXPR_P (retval))
|| TREE_CODE (retval) == PARM_DECL)
&& DECL_CONTEXT (retval) == current_function_decl
&& !TREE_STATIC (retval)
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-return1.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-return1.C
new file mode 100644
index 0000000..4b353b6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-return1.C
@@ -0,0 +1,26 @@
+// PR c++/57437
+// { dg-require-effective-target c++11 }
+
+struct A {
+ int i;
+
+ A(): i(42) {}
+ A(const A&) = default;
+ A(A&& a): i(a.i) { a.i = 0; }
+};
+
+int main()
+{
+ A x;
+
+ auto y = [x] () mutable {
+ x.i++;
+ return x;
+ };
+
+ if (y().i != 43)
+ __builtin_abort ();
+
+ if (y().i != 44)
+ __builtin_abort ();
+}