]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/57437 (C++11: mutable lambdas)
authorJason Merrill <jason@redhat.com>
Tue, 9 Jul 2013 17:56:32 +0000 (13:56 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 9 Jul 2013 17:56:32 +0000 (13:56 -0400)
PR c++/57437
* typeck.c (check_return_expr): Lambda proxies aren't eligible
for nrv or return by move.

From-SVN: r200843

gcc/cp/ChangeLog
gcc/cp/typeck.c
gcc/testsuite/g++.dg/cpp0x/lambda/lambda-return1.C [new file with mode: 0644]

index 2d6fa73d01178b02d8db6c6b3404fae8490b3ae8..68c6a09cff93004960e392a20ce638d14fe68977 100644 (file)
@@ -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.
index 462abdd5039dffe0fce401c3a012dede3e434287..6f7d489287918bd4c2604b649ebde7507bf8d1c3 100644 (file)
@@ -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 (file)
index 0000000..4b353b6
--- /dev/null
@@ -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 ();
+}