At the Bristol C++ meeting we voted to accept generalized lambda capture
initializers (e.g. [x = 42, y = std::move(y)]{ ... }), which were part
of the initial implementation of lambdas in GCC, so initial support for
C++1y is just a matter of checking cxx_dialect to avoid the pedwarn.
The only thing missing from our implementation is support for
list-initialization as well as = initialization; I'll add that soon.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit a920644105779dceffd5912822b10b331457a227
Author: Jason Merrill <ja...@redhat.com>
Date: Mon Apr 22 12:56:01 2013 -0400
N3648
* parser.c (cp_parser_lambda_introducer): Make lambda capture init
pedwarn unconditional except in C++1y mode.
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 1893482..1fbc9bd 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -8518,9 +8518,10 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr)
{
/* An explicit expression exists. */
cp_lexer_consume_token (parser->lexer);
- pedwarn (input_location, OPT_Wpedantic,
- "ISO C++ does not allow initializers "
- "in lambda expression capture lists");
+ if (cxx_dialect < cxx1y)
+ pedwarn (input_location, 0,
+ "lambda capture initializers "
+ "only available with -std=c++1y or -std=gnu++1y");
capture_init_expr = cp_parser_assignment_expression (parser,
/*cast_p=*/true,
&idk);
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce-ext.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce-ext.C
deleted file mode 100644
index 9b5ab79..0000000
--- a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce-ext.C
+++ /dev/null
@@ -1,27 +0,0 @@
-// Testcase for an extension to allow return type deduction when the lambda
-// contains more than just a single return-statement.
-
-// { dg-options -std=c++0x }
-// { dg-do run }
-
-bool b;
-template <class T>
-T f (T t)
-{
- return [=] {
- auto i = t+1;
- if (b)
- return i+1;
- else
- return i+1;
- }();
-}
-
-int main()
-{
- // Pointless, but well-formed.
- [] { return 1; return 2; }();
-
- if (f(1) != 3)
- return 1;
-}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-init.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-init.C
deleted file mode 100644
index 03c94e9..0000000
--- a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-init.C
+++ /dev/null
@@ -1,8 +0,0 @@
-// Test for the explicit initializer extension
-// { dg-options "-std=c++0x" }
-
-int main()
-{
- int j = [i = 2]{sizeof(i); return i;}();
- return (j != 2);
-}
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-deduce-mult.C b/gcc/testsuite/g++.dg/cpp1y/lambda-deduce-mult.C
new file mode 100644
index 0000000..1181a80
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-deduce-mult.C
@@ -0,0 +1,27 @@
+// Testcase for an extension to allow return type deduction when the lambda
+// contains more than just a single return-statement.
+
+// { dg-options -std=c++1y }
+// { dg-do run }
+
+bool b;
+template <class T>
+T f (T t)
+{
+ return [=] {
+ auto i = t+1;
+ if (b)
+ return i+1;
+ else
+ return i+1;
+ }();
+}
+
+int main()
+{
+ // Pointless, but well-formed.
+ [] { return 1; return 2; }();
+
+ if (f(1) != 3)
+ return 1;
+}
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-init.C b/gcc/testsuite/g++.dg/cpp1y/lambda-init.C
new file mode 100644
index 0000000..a443642
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-init.C
@@ -0,0 +1,8 @@
+// Test for the explicit initializer extension of C++1y
+// { dg-options "-std=c++1y" }
+
+int main()
+{
+ int j = [i = 2]{sizeof(i); return i;}();
+ return (j != 2);
+}
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-init1.C b/gcc/testsuite/g++.dg/cpp1y/lambda-init1.C
new file mode 100644
index 0000000..6411fca
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-init1.C
@@ -0,0 +1,13 @@
+// N3648: capture init
+// { dg-options "-std=c++1y -w" }
+// { dg-do run }
+
+int main()
+{
+ int x = 41;
+ auto r = [x = x+1]{ return x; }();
+ if (r != 42) __builtin_abort();
+
+ static auto *p = &r;
+ [&x=r]{ if (&x != p) __builtin_abort(); }();
+}
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-init2.C b/gcc/testsuite/g++.dg/cpp1y/lambda-init2.C
new file mode 100644
index 0000000..068621d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-init2.C
@@ -0,0 +1,13 @@
+// N3648: redundancy and capture init
+// { dg-options "-std=c++1y -pedantic-errors" }
+
+int main()
+{
+ int x = 42;
+ [=,x]{}; // { dg-error "redundant" }
+ [=,&x]{};
+ [&,&x]{}; // { dg-error "redundant" }
+ [&,x]{};
+ [=,x=24]{};
+ [&,&r=x]{};
+}
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-init3.C b/gcc/testsuite/g++.dg/cpp1y/lambda-init3.C
new file mode 100644
index 0000000..9044be6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-init3.C
@@ -0,0 +1,11 @@
+// N3648: capture init at non-block scope
+// { dg-options "-std=c++1y -w" }
+// { dg-do run }
+
+int i = 42;
+int j = [x=i]{ return x; }();
+
+int main()
+{
+ if (j != 42) __builtin_abort();
+}
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-init4.C b/gcc/testsuite/g++.dg/cpp1y/lambda-init4.C
new file mode 100644
index 0000000..da4ea37
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-init4.C
@@ -0,0 +1,14 @@
+// N3648: capture init example from paper
+// { dg-options "-std=c++1y" }
+// { dg-do run }
+
+int x = 4;
+auto y = [&r = x, x = x+1]()->int {
+ r += 2;
+ return x+2;
+}(); // Updates ::x to 6, and initializes y to 7.
+
+int main()
+{
+ if (x != 6 || y != 7) __builtin_abort();
+}