summaryrefslogtreecommitdiff
path: root/gcc/testsuite/g++.dg/cpp0x/lambda
diff options
context:
space:
mode:
authorupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
committerupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
commit554fd8c5195424bdbcabf5de30fdc183aba391bd (patch)
tree976dc5ab7fddf506dadce60ae936f43f58787092 /gcc/testsuite/g++.dg/cpp0x/lambda
downloadcbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2
cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository.
Diffstat (limited to 'gcc/testsuite/g++.dg/cpp0x/lambda')
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-50220.C9
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-98.C8
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-array.C20
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-capture-const-ref-neg.C14
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-capture-const-ref.C15
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const-neg.C19
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const.C20
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv.C14
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv2.C12
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv3.C12
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv4.C13
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv5.C15
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-copy-default-neg.C13
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-copy-default.C14
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-copy-neg.C13
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-copy.C14
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ctor-neg.C25
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ctors.C18
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-debug.C15
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce-ext-neg.C24
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce-ext-neg2.C22
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce-ext.C27
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce-neg.C10
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce.C29
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce2.C7
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-defarg.C6
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-defarg2.C7
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-direct-init.C14
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-eh.C35
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-eh2.C17
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-errloc.C18
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-errloc2.C19
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-field-names.C21
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice1.C13
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice2.C16
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice3.C23
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice4.C14
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-in-class-neg.C35
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-in-class.C36
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-init.C8
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-lookup-neg.C7
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mangle.C103
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mangle2.C21
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mixed.C13
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mutable.C16
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested.C63
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested2.C31
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested3.C12
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-non-const.C19
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nop.C19
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ns-scope.C18
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-pass.C27
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-qualified.C17
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-recursive.C21
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ref-default.C15
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ref.C15
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ref2.C13
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-std-function.C22
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template.C41
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template2.C20
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this.C13
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this2.C17
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this3.C14
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this4.C13
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-type.C74
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-uneval.C7
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-use.C12
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-use2.C11
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic1.C15
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-warn1.C8
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-warn2.C7
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-warn3.C12
72 files changed, 1400 insertions, 0 deletions
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-50220.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-50220.C
new file mode 100644
index 000000000..240143cf6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-50220.C
@@ -0,0 +1,9 @@
+// PR c++/50220
+// { dg-options -std=c++0x }
+
+template<typename Foo> struct Foobar {};
+
+void foobar(const Foobar<void>& obj)
+{
+ [obj](){}();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-98.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-98.C
new file mode 100644
index 000000000..ff1085f30
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-98.C
@@ -0,0 +1,8 @@
+// PR c++/46159
+// { dg-options -std=c++98 }
+
+void
+f()
+{
+ int **p = new(int(*[2]));
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-array.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-array.C
new file mode 100644
index 000000000..2129051ed
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-array.C
@@ -0,0 +1,20 @@
+// Test that array capture by copy works.
+// { dg-options -std=c++0x }
+// { dg-do run }
+
+struct A
+{
+ int i;
+ A(int i): i(i) {}
+ A(const A& a): i(a.i+1) {}
+};
+
+int main()
+{
+ A ar[4][3] = { { 10, 20, 30 },
+ { 40, 50, 60 },
+ { 70, 80, 90 },
+ { 100, 110, 120 } };
+ int i = [ar] { return ar[1][1]; }().i;
+ return (i!= 52);
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-capture-const-ref-neg.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-capture-const-ref-neg.C
new file mode 100644
index 000000000..7d1a1bd89
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-capture-const-ref-neg.C
@@ -0,0 +1,14 @@
+// { dg-options "-std=c++0x" }
+#include <cassert>
+
+int main() {
+ int i = 1, j = 2;
+ const int& ci = i;
+ [&ci, &j] () -> void { j = ci; } ();
+ assert(i == 1);
+ assert(j == 1);
+ [&ci] () -> void { ci = 0; } (); // { dg-error "" "cannot assign to const int&" }
+
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-capture-const-ref.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-capture-const-ref.C
new file mode 100644
index 000000000..704c24085
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-capture-const-ref.C
@@ -0,0 +1,15 @@
+// { dg-do run }
+// { dg-options "-std=c++0x" }
+#include <cassert>
+
+int main() {
+ int i = 1, j = 2;
+ const int& ci = i;
+ [&ci, &j] () -> void { j = ci; } ();
+ assert(i == 1);
+ assert(j == 1);
+ //[&ci] () -> void { ci = 0; } (); { dg-error: cannot assign to const int& }
+
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const-neg.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const-neg.C
new file mode 100644
index 000000000..7e7541ca2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const-neg.C
@@ -0,0 +1,19 @@
+// { dg-options "-std=c++0x" }
+
+#include <cassert>
+
+template<typename F>
+void call(const F& f) { f(); }
+
+int main() {
+ call([] () -> void {});
+ call([] () mutable -> void {});
+
+ int i = -1;
+ call([&i] () -> void { i = 0; });
+ assert(i == 0);
+ call([i] () -> void { i = 0; }); // { dg-error "" "assignment to non-reference capture in const lambda" }
+
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const.C
new file mode 100644
index 000000000..5f6f0b3dc
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const.C
@@ -0,0 +1,20 @@
+// { dg-do run }
+// { dg-options "-std=c++0x" }
+
+#include <cassert>
+
+template<typename F>
+void call(const F& f) { f(); }
+
+int main() {
+ call([] () -> void {});
+ //call([] () mutable -> void {}); // { dg-error: "`f' does not have const `operator()'" }
+
+ int i = -1;
+ call([&i] () -> void { i = 0; });
+ assert(i == 0);
+ //call([i] () -> void { i = 0; }); // { dg-error: "assignment to non-reference capture in const lambda" }
+
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv.C
new file mode 100644
index 000000000..5409d5ca3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv.C
@@ -0,0 +1,14 @@
+// Test for conversion from stateless lambda to function pointer.
+
+// { dg-options -std=c++0x }
+// { dg-final { scan-assembler "weak\[^\n\r\]*_?_ZZ1fvENKUlvE_cvPFvvEEv" { target { ! { *-*-darwin* *-*-mingw* *-*-cygwin *-*-hpux10* } } } } }
+
+inline void f()
+{
+ void (*pfn)() = []{};
+}
+
+int main()
+{
+ f();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv2.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv2.C
new file mode 100644
index 000000000..fc19c9969
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv2.C
@@ -0,0 +1,12 @@
+// Test for conversion from stateless lambda to function pointer.
+
+// { dg-options -std=c++0x }
+// { dg-do run }
+
+typedef int (*pfn)(int);
+
+int main()
+{
+ pfn p = [](int i) { return i-42; };
+ return p (42);
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv3.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv3.C
new file mode 100644
index 000000000..e4e7daffd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv3.C
@@ -0,0 +1,12 @@
+// Conversion to a function pointer uses a generic thunk, which doesn't
+// work properly for variadics. Make sure that we can still use the lambda
+// normally.
+
+// { dg-options -std=c++0x }
+
+void f()
+{
+ auto l = [](...){};
+ void (*p1)(...) = l; // { dg-bogus "sorry" "" { xfail *-*-* } }
+ l(); // OK
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv4.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv4.C
new file mode 100644
index 000000000..6584d28b9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv4.C
@@ -0,0 +1,13 @@
+// PR c++/43641
+// { dg-options "-std=c++0x" }
+
+struct B
+{
+ int i;
+};
+
+void func()
+{
+ [](const B& b) -> const int& { return b.i; };
+ [](const B& b) { return b; };
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv5.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv5.C
new file mode 100644
index 000000000..53d8e995e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv5.C
@@ -0,0 +1,15 @@
+// PR c++/45080
+// { dg-options -std=c++0x }
+
+typedef void(*pfn)();
+
+template<typename=int>
+void f()
+{
+ pfn fn = []{};
+}
+
+void test()
+{
+ f();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-copy-default-neg.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-copy-default-neg.C
new file mode 100644
index 000000000..1af2a95d8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-copy-default-neg.C
@@ -0,0 +1,13 @@
+// { dg-options "-std=c++0x" }
+
+int main() {
+ int i;
+ const char* s;
+ [=] () -> void { i; s; i; s; } ();
+
+ [] () -> void { i; } (); // { dg-error "" "`i' is not captured" }
+ [1] () -> void {} (); // { dg-error "expected identifier" }
+
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-copy-default.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-copy-default.C
new file mode 100644
index 000000000..239a99cbf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-copy-default.C
@@ -0,0 +1,14 @@
+// { dg-do run }
+// { dg-options "-std=c++0x" }
+
+int main() {
+ int i;
+ const char* s;
+ [=] () -> void { i; s; i; s; } ();
+
+ //[] () -> void { i; } (); // { dg-error: "`i' is not in scope" }
+ //[1] () -> void {} (); // { dg-error: "expected identifier" }
+
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-copy-neg.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-copy-neg.C
new file mode 100644
index 000000000..d77e57e63
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-copy-neg.C
@@ -0,0 +1,13 @@
+// { dg-options "-std=c++0x" }
+
+int main() {
+ int i;
+ const char* s;
+ [i, s] () -> void { i; s; } ();
+
+ [] () -> void { i; } (); // { dg-error "" "`i' is not captured" }
+ [1] () -> void {} (); // { dg-error "expected identifier" }
+
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-copy.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-copy.C
new file mode 100644
index 000000000..7356872e1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-copy.C
@@ -0,0 +1,14 @@
+// { dg-do run }
+// { dg-options "-std=c++0x" }
+
+int main() {
+ int i;
+ const char* s;
+ [i, s] () -> void { i; s; } ();
+
+ //[] () -> void { i; } (); // { dg-error: "`i' is not in scope" }
+ //[1] () -> void {} (); // { dg-error: "expected identifier" }
+
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ctor-neg.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ctor-neg.C
new file mode 100644
index 000000000..76ed7445f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ctor-neg.C
@@ -0,0 +1,25 @@
+// { dg-options -std=c++0x }
+
+void f()
+{
+ int i;
+ auto lam = [i]{}; // { dg-message "" }
+ decltype(lam) lam2 = { 1 }; // { dg-error "" "not an aggregate" }
+ decltype(lam) lam3; // { dg-error "" "deleted default ctor" }
+ lam3 = lam; // { dg-error "" "deleted assignment op" }
+}
+
+template <class T>
+void g(T i)
+{
+ auto lam = [i]{}; // { dg-message "" }
+ decltype(lam) lam2 = { 1 }; // { dg-error "" "not an aggregate" }
+ decltype(lam) lam3; // { dg-error "" "deleted default ctor" }
+ lam3 = lam; // { dg-error "" "deleted assignment op" }
+}
+
+int main()
+{
+ f();
+ g(1);
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ctors.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ctors.C
new file mode 100644
index 000000000..e263145b0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ctors.C
@@ -0,0 +1,18 @@
+// { dg-options -std=c++0x }
+// { dg-do run }
+
+struct A
+{
+ A() { }
+ A(A&) { }
+ A(A&&) { }
+};
+
+int main()
+{
+ A a;
+ auto lam4 = [a]{}; // OK, implicit move ctor
+ lam4();
+ auto lam5 = lam4; // OK, implicit copy ctor
+ lam5();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-debug.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-debug.C
new file mode 100644
index 000000000..07fc1896c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-debug.C
@@ -0,0 +1,15 @@
+// PR c++/43502
+// { dg-options "-std=c++0x -fcompare-debug" }
+
+void g (int n)
+{
+ int bef ([]{return 0;}());
+}
+struct S {
+ void f (int = []{return 0;}(), int = [] { return 0;}());
+};
+int main ()
+{
+ S ().f ();
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce-ext-neg.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce-ext-neg.C
new file mode 100644
index 000000000..bfe7acab6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce-ext-neg.C
@@ -0,0 +1,24 @@
+// 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 }
+
+bool b;
+template <class T>
+T f (T t)
+{
+ return [=]
+ {
+ auto i = t+1;
+ if (b)
+ return i+1;
+ else
+ return i+2; // { dg-error "lambda return type" }
+ }();
+}
+
+int main()
+{
+ if (f(1) != 3)
+ return 1;
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce-ext-neg2.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce-ext-neg2.C
new file mode 100644
index 000000000..a236e6d11
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce-ext-neg2.C
@@ -0,0 +1,22 @@
+// Test that in pedantic mode, we warn about the extension to allow return
+// type deduction when the lambda contains more than just a single
+// return-statement.
+
+// { dg-options "-std=c++0x -pedantic" }
+
+bool b;
+template <class T>
+T f (T t)
+{
+ [=] { return t+1; }; // OK
+ return [=] {
+ auto i = t+1;
+ return i+1; // { dg-warning "only statement" }
+ }();
+}
+
+int main()
+{
+ if (f(1) != 3)
+ return 1;
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce-ext.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce-ext.C
new file mode 100644
index 000000000..9b5ab7983
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce-ext.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++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-deduce-neg.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce-neg.C
new file mode 100644
index 000000000..4abdf59a6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce-neg.C
@@ -0,0 +1,10 @@
+// { dg-options "-std=c++0x" }
+#include <cassert>
+
+int main() {
+ int i = 0;
+ int& r = [&] () { return i; } (); // { dg-error "" "invalid initialization of non-const reference of type .int&. from a temporary of type .int." }
+
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce.C
new file mode 100644
index 000000000..cc5cc5402
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce.C
@@ -0,0 +1,29 @@
+// { dg-do run }
+// { dg-options "-std=c++0x" }
+#include <cassert>
+
+int main() {
+ [] {};
+ [] {} ();
+ [] () {};
+ [] () {} ();
+ [] () { return "lambda"; };
+
+ int i = 1, j = 2;
+ [&i, j] () { i = j; } ();
+ assert(i == 2);
+ assert(j == 2);
+
+ i = [] () { return 3; } ();
+ assert(i == 3);
+
+ int k = [&] () { return i; } ();
+
+ []{ return; };
+
+ int array[] = { 1, 2, 3 };
+ int* p = [&] () { return array; } ();
+
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce2.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce2.C
new file mode 100644
index 000000000..718d49cd9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce2.C
@@ -0,0 +1,7 @@
+// PR c++/43875
+// { dg-options "-std=c++0x" }
+
+int main()
+{
+ auto x2 = []{ return { 1, 2 }; }; // { dg-message "return" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-defarg.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-defarg.C
new file mode 100644
index 000000000..069935823
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-defarg.C
@@ -0,0 +1,6 @@
+// { dg-options "-std=c++0x -pedantic-errors" }
+
+int main()
+{
+ [](int a = 1) { return a; }(); // { dg-error "" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-defarg2.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-defarg2.C
new file mode 100644
index 000000000..f47c5ba27
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-defarg2.C
@@ -0,0 +1,7 @@
+// PR c++/43886
+// { dg-options -std=c++0x }
+
+void f2() {
+ int i = 1;
+ void g5(int = ([]{ return sizeof i; })());
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-direct-init.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-direct-init.C
new file mode 100644
index 000000000..bbc2a1ca5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-direct-init.C
@@ -0,0 +1,14 @@
+// Test that capture by copy uses direct-initialization.
+// { dg-options "-std=c++0x" }
+
+struct A
+{
+ A();
+ explicit A(const A&);
+};
+
+int main()
+{
+ A a;
+ [a]{};
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-eh.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-eh.C
new file mode 100644
index 000000000..ea5060d1a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-eh.C
@@ -0,0 +1,35 @@
+// Test that we properly clean up if we get an exception in the middle of
+// constructing the closure object.
+// { dg-options -std=c++0x }
+
+// This test fails because of PR 41449; it isn't a lambda issue.
+// { dg-do run { xfail *-*-* } }
+
+struct A
+{
+ A() {}
+ A(const A&) { throw 1; }
+};
+
+int bs;
+struct B
+{
+ B() { ++bs; }
+ B(const B&) { ++bs; }
+ ~B() { --bs; }
+};
+
+int main()
+{
+ {
+ B b1, b2;
+ A a;
+
+ try
+ {
+ [b1, a, b2]{ };
+ }
+ catch(...) {}
+ }
+ return bs;
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-eh2.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-eh2.C
new file mode 100644
index 000000000..0c94b554f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-eh2.C
@@ -0,0 +1,17 @@
+// PR c++/47263
+// PR c++/49260
+// { dg-options "-std=c++0x -fno-asynchronous-unwind-tables -fno-dwarf2-cfi-asm" }
+// { dg-do run }
+
+#include <exception>
+
+int main( void )
+{
+ std::set_unexpected( []{ throw 0; } );
+ try
+ {
+ []() throw( int ) { throw nullptr; }();
+ }
+ catch( int )
+ { }
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-errloc.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-errloc.C
new file mode 100644
index 000000000..f4766691e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-errloc.C
@@ -0,0 +1,18 @@
+// Test that error messages about creating the closure object refer to
+// the lambda-introducer.
+// { dg-options -std=c++0x }
+
+struct A
+{
+ A();
+ A(const A& a) = delete; // { dg-error "declared" }
+};
+
+int main()
+{
+ A ar[4][3];
+ [ar] { }; // { dg-error "3:" }
+
+ A a;
+ [a] { }; // { dg-error "3:" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-errloc2.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-errloc2.C
new file mode 100644
index 000000000..dab53f127
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-errloc2.C
@@ -0,0 +1,19 @@
+// PR c++/42399
+// { dg-options "-std=c++0x" }
+
+struct A {
+ A();
+ A(const A&) = delete; // { dg-error "declared" }
+};
+
+template <class T>
+void f()
+{
+ T t;
+ [t] { return 0; }; // { dg-error "use" }
+}
+
+int main()
+{
+ f<A>(); // { dg-message "instantiated" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-field-names.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-field-names.C
new file mode 100644
index 000000000..b292d8898
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-field-names.C
@@ -0,0 +1,21 @@
+// "For each entity captured by copy, an unnamed non-static data member is
+// declared in the closure type" -- test that there isn't a member of the
+// closure with the same name as the captured variable.
+
+// { dg-options -std=c++0x }
+
+template <class T>
+struct A: public T
+{
+ A(T t): T(t) { }
+ int f() { return this->i; } // { dg-error "" "no member named i" }
+};
+
+int main()
+{
+ int i = 42;
+ auto lam = [i]{ };
+ lam.i = 24; // { dg-error "" "no member named i" }
+ A<decltype(lam)> a(lam);
+ return a.f();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice1.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice1.C
new file mode 100644
index 000000000..1ea8f4d7b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice1.C
@@ -0,0 +1,13 @@
+// PR c++/43790
+// { dg-options "-std=c++0x" }
+
+struct A
+{
+ int f();
+};
+
+int main()
+{
+ A a;
+ auto l = [] () { return a.f(); }; // { dg-error "not captured|return" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice2.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice2.C
new file mode 100644
index 000000000..352137aad
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice2.C
@@ -0,0 +1,16 @@
+// PR c++/42083
+// { dg-options "-std=c++0x" }
+
+template<typename F>
+decltype(F()) run(F f) // { dg-message "note" }
+{
+ return f();
+}
+
+int main()
+{
+ auto l = []() { return 5; };
+
+ run(l); // { dg-error "no match" }
+ // { dg-message "candidate" "candidate note" { target *-*-* } 14 }
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice3.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice3.C
new file mode 100644
index 000000000..8ff36478d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice3.C
@@ -0,0 +1,23 @@
+// PR c++/47795
+// { dg-options "-std=c++0x" }
+
+class Klass
+{
+ unsigned int local;
+public:
+ bool dostuff();
+};
+
+bool Klass::dostuff()
+{
+ auto f = []() -> bool {
+ if (local & 1) { return true; } // { dg-error "not captured" }
+ return false;
+ };
+}
+
+int main()
+{
+ Klass c;
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice4.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice4.C
new file mode 100644
index 000000000..77c773bbd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice4.C
@@ -0,0 +1,14 @@
+// PR c++/47242
+// { dg-options "-std=c++0x" }
+
+template < typename > void
+bar ()
+{
+ [i]{}; // { dg-error "declared|invalid" }
+}
+
+void
+foo ()
+{
+ bar<int>();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-in-class-neg.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-in-class-neg.C
new file mode 100644
index 000000000..a93857e46
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-in-class-neg.C
@@ -0,0 +1,35 @@
+// { dg-options "-std=c++0x" }
+
+#include <cassert>
+
+class C {
+ private:
+ int m_i;
+
+ public:
+ C() : m_i(-1) {
+ [] { this; } (); // { dg-error "not captured" }
+ [this] () -> void { m_i = 0; } ();
+ assert(m_i == 0);
+ [this] () -> void { this->m_i = 1; } ();
+ assert(m_i == 1);
+ [&] () -> void { m_i = 2; } ();
+ assert(m_i == 2);
+ [&] () -> void { this->m_i = 3; } ();
+ assert(m_i == 3);
+ [=] () -> void { m_i = 4; } (); // copies 'this' or --copies-m_i--?
+ assert(m_i == 4);
+ [=] () -> void { this->m_i = 5; } ();
+ assert(m_i == 5);
+ }
+
+};
+
+int main() {
+ C c;
+
+ [this] () -> void {} (); // { dg-error "use of 'this' in non-member function" }
+
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-in-class.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-in-class.C
new file mode 100644
index 000000000..33f4301e4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-in-class.C
@@ -0,0 +1,36 @@
+// { dg-do run }
+// { dg-options "-std=c++0x" }
+
+#include <cassert>
+
+class C {
+ private:
+ int m_i;
+
+ public:
+ C() : m_i(-1) {
+ //[] { this; } ();
+ [this] () -> void { m_i = 0; } ();
+ assert(m_i == 0);
+ [this] () -> void { this->m_i = 1; } ();
+ assert(m_i == 1);
+ [&] () -> void { m_i = 2; } ();
+ assert(m_i == 2);
+ [&] () -> void { this->m_i = 3; } ();
+ assert(m_i == 3);
+ [=] () -> void { m_i = 4; } (); // copies 'this' or --copies-m_i--?
+ assert(m_i == 4);
+ [=] () -> void { this->m_i = 5; } ();
+ assert(m_i == 5);
+ }
+
+};
+
+int main() {
+ C c;
+
+ //[this] () -> void {} (); // { dg-error: "cannot capture `this' outside of class method" }
+
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-init.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-init.C
new file mode 100644
index 000000000..03c94e959
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-init.C
@@ -0,0 +1,8 @@
+// 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/cpp0x/lambda/lambda-lookup-neg.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-lookup-neg.C
new file mode 100644
index 000000000..e07e892a1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-lookup-neg.C
@@ -0,0 +1,7 @@
+// Test that we don't crash on a failed lookup.
+// { dg-options -std=c++0x }
+
+int main()
+{
+ [i]{}; // { dg-error "not declared" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mangle.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mangle.C
new file mode 100644
index 000000000..5c9b483d3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mangle.C
@@ -0,0 +1,103 @@
+// Test lambda mangling
+// { dg-require-weak "" }
+// { dg-options "-std=c++0x -fno-inline" }
+
+template<typename F> int algo(F fn) { return fn(); }
+inline void g(int n) {
+ int bef(int i = []{ return 1; }());
+ // Default arguments of block-extern function declarations
+ // remain in the context of the encloding function body.
+ // The closure type is encoded as Z1giEUlvE_.
+ // The call operator of that type is _ZZ1giENKUlvE_clEv.
+
+// { dg-final { scan-assembler "_ZZ1giENKUlvE_clEv" } }
+// { dg-final { scan-assembler "weak\[^\n\r\]*_?_ZZ1giENKUlvE_clEv" { target { ! { *-*-darwin* *-*-mingw* *-*-cygwin } } } } }
+
+ algo([=]{return n+bef();});
+ // The captured entities do not participate in <lambda-sig>
+ // and so this closure type has the same <lambda-sig> as
+ // the previous one. It encoding is therefore Z1giEUlvE0_
+ // and the call operator is _ZZ1giENKUlvE0_clEv. The
+ // instance of "algo" being called is then
+ // _Z4algoIZ1giEUlvE0_EiT_.
+
+// { dg-final { scan-assembler "_Z4algoIZ1giEUlvE0_EiT_" } }
+// { dg-final { scan-assembler "_ZZ1giENKUlvE0_clEv" } }
+
+ int i = []{return 1;}();
+
+}
+
+struct S {
+ void f(int =
+ // Type: ZN1S1fEiiEd0_UlvE_
+ // Operator: _ZZN1S1fEiiEd0_NKUlvE_clEv
+// { dg-final { scan-assembler "_ZZN1S1fEiiEd0_NKUlvE_clEv" } }
+// { dg-final { scan-assembler "weak\[^\n\r\]*_?_ZZN1S1fEiiEd0_NKUlvE_clEv" { target { ! { *-*-darwin* *-*-mingw* *-*-cygwin } } } } }
+ []{return 1;}()
+ // Type: ZN1S1fEiiEd0_UlvE0_
+ // Operator: _ZZN1S1fEiiEd0_NKUlvE0_clEv
+// { dg-final { scan-assembler "_ZZN1S1fEiiEd0_NKUlvE0_clEv" } }
+ + []{return 2;}(),
+ int =
+ // Type: ZN1S1fEiiEd_UlvE_
+ // Operator: _ZZN1S1fEiiEd_NKUlvE_clEv
+// { dg-final { scan-assembler "_ZZN1S1fEiiEd_NKUlvE_clEv" } }
+ []{return 3;}());
+};
+
+template<typename T> struct R {
+ static int x;
+};
+template<typename T> int R<T>::x = []{return 1;}();
+template int R<int>::x;
+// Type of lambda in intializer of R<int>::x: N1RIiE1xMUlvE_E
+// Corresponding operator(): _ZNK1RIiE1xMUlvE_clEv
+// { dg-final { scan-assembler "_ZNK1RIiE1xMUlvE_clEv" } }
+// { dg-final { scan-assembler "weak\[^\n\r\]*_?_ZNK1RIiE1xMUlvE_clEv" { target { ! { *-*-mingw* *-*-cygwin } } } } }
+
+void bar()
+{
+ // lambdas in non-vague linkage functions have internal linkage.
+ // { dg-final { scan-assembler-not "weak\[^\n\r\]*bar\[^\n\r\]*Ul" } }
+ []{}();
+}
+
+// lambdas used in non-template, non-class body initializers are internal.
+// { dg-final { scan-assembler-not "weak\[^\n\r\]*_ZNKUlv" } }
+// { dg-final { scan-assembler-not "weak\[^\n\r\]*variable" } }
+int variable = []{return 1;}();
+
+// And a template instantiated with such a lambda is also internal.
+// { dg-final { scan-assembler-not "weak\[^\n\r\]*algoIUl" } }
+int var2 = algo([]{return 1;});
+
+// As are lambdas used in non-class-body default arguments.
+// { dg-final { scan-assembler-not "weak\[^\n\r\]*function" } }
+void function (int i = []{return 1;}()+[]{return 1;}());
+
+struct Foo
+{
+ static int Int;
+ void Bar(int);
+};
+
+int Foo::Int = []{return 1;}();
+// Even default arguments for member functions that appear outside the
+// class body are internal.
+// { dg-final { scan-assembler-not "weak\[^\n\r\]*Foo" } }
+void Foo::Bar(int i = []{return 1;}()) {}
+
+// Even default arguments for function templates.
+// { dg-final { scan-assembler-not "weak\[^\n\r\]*fn2\[^\n\r\]*Ulv" } }
+template <class T>
+void fn2 (T t = []{return 1;}()) {}
+
+int main()
+{
+ g(42);
+ S().f();
+ function();
+ Foo().Bar();
+ fn2<int>();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mangle2.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mangle2.C
new file mode 100644
index 000000000..4b7d15ad9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mangle2.C
@@ -0,0 +1,21 @@
+// PR c++/49276
+// { dg-do compile }
+// { dg-options "-std=c++0x" }
+
+template <int N>
+struct F
+{
+ template <typename U> F (U);
+};
+
+struct S
+{
+ void foo (F <0> x = [] {}) {}
+};
+
+int
+main ()
+{
+ S s;
+ s.foo ();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mixed.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mixed.C
new file mode 100644
index 000000000..ed0565fa9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mixed.C
@@ -0,0 +1,13 @@
+// { dg-do run }
+// { dg-options "-std=c++0x" }
+#include <cassert>
+
+int main() {
+ int i = 1, j = 2;
+ [&i, j] () mutable -> void { i = 0; j = 0; } ();
+ assert(i == 0);
+ assert(j == 2);
+
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mutable.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mutable.C
new file mode 100644
index 000000000..73a4d1bac
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mutable.C
@@ -0,0 +1,16 @@
+// { dg-do run }
+// { dg-options "-std=c++0x" }
+#include <cassert>
+
+int main() {
+ int i = 1;
+ const char* s1 = "hello";
+ const char* s2 = s1;
+ [i, s2] () mutable -> void { i = 2; s2 = "world"; } ();
+ //[i, s2] () -> void { i = 2; s2 = "world"; } (); // { dg-error: "assignment of data-member in read-only structure" }
+ assert(i == 1);
+ assert(s1 == s2);
+
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested.C
new file mode 100644
index 000000000..feb0cde59
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested.C
@@ -0,0 +1,63 @@
+// { dg-do run }
+// { dg-options "-std=c++0x" }
+
+#include <cassert>
+
+struct A {
+ int i;
+ A(): i(42) { }
+ int f() {
+ return [this]{
+ return [=]{ return i; }();
+ }();
+ }
+};
+
+int main() {
+ int i = 1;
+
+ [] (int& i) -> void {
+ [&] () -> void {
+ i = 2;
+ } ();
+ } (i);
+
+ assert(i == 2);
+
+ [&] () -> void {
+ [&i] () -> void {
+ i = 3;
+ } ();
+ } ();
+
+ assert(i == 3);
+
+ [&] () -> void {
+ [&] () -> void {
+ i = 4;
+ } ();
+ } ();
+
+ assert(i == 4);
+ i = 4;
+
+ [&] () -> void {
+ [=] () mutable -> void {
+ i = 5;
+ } ();
+ } ();
+
+ assert(i == 4);
+
+ [=] () mutable -> void {
+ [&] () -> void {
+ i = 6;
+ } ();
+ } ();
+
+ assert(i == 4);
+
+ assert (A().f() == 42);
+
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested2.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested2.C
new file mode 100644
index 000000000..b78874855
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested2.C
@@ -0,0 +1,31 @@
+// Testcase from N2998
+// { dg-options -std=c++0x }
+
+void f1(int i) {
+ int const N = 20;
+ auto m1 = [=]{
+ int const M = 30;
+ auto m2 = [i]{
+ int x[N][M]; // OK: N and M are not "used"
+ x[0][0] = i; // OK: i is explicitly captured by m2
+ // and implicitly captured by m1
+ };
+ };
+ struct s1 {
+ int f;
+ int work(int n) {
+ int m = n*n;
+ int j = 40;
+ auto m3 = [this,m]{
+ /*auto m4=*/[&,j]{ // { dg-error "j. is not captured" }
+ int x = n; // { dg-error "n. is not captured" }
+ x += m; // OK: m implicitly captured by m4
+ // and explicitly captured by m3
+ x += i; // { dg-error "i. is not captured" }
+ x += f; // OK: this captured implicitly by m4
+ // and explicitly by m3
+ };
+ };
+ }
+ };
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested3.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested3.C
new file mode 100644
index 000000000..2cc6f9640
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested3.C
@@ -0,0 +1,12 @@
+// PR c++/41896
+// { dg-options "-std=c++0x" }
+
+void nested_lambda()
+{
+ float val;
+
+ [val]()
+ {
+ [val](){};
+ };
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-non-const.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-non-const.C
new file mode 100644
index 000000000..b6489de4b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-non-const.C
@@ -0,0 +1,19 @@
+// { dg-do run }
+// { dg-options "-std=c++0x" }
+
+#include <cassert>
+
+template<typename F>
+void call(F f) { f(); }
+
+int main() {
+ call([] () -> void {});
+ call([] () mutable -> void {});
+
+ int i = -1;
+ call([i] () mutable -> void { i = 0; });
+ assert(i == -1);
+
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nop.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nop.C
new file mode 100644
index 000000000..74149b231
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nop.C
@@ -0,0 +1,19 @@
+// { dg-do run }
+// { dg-options "-std=c++0x" }
+#include <cassert>
+
+int main() {
+ int i = 1, j = 2;
+ [i, j] () -> void {} ();
+ assert(i == 1);
+ assert(j == 2);
+ [&i, &j] () -> void {} ();
+ assert(i == 1);
+ assert(j == 2);
+ [] (int x) -> void {} (1);
+ [] (int& x) -> void {} (i);
+ [] (int x, int y) -> void {} (i, j);
+
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ns-scope.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ns-scope.C
new file mode 100644
index 000000000..cde0c2e53
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ns-scope.C
@@ -0,0 +1,18 @@
+// { dg-options -std=c++0x }
+// { dg-do run }
+
+auto f = [](int i) { return i+1; };
+
+int g(int i = [] { return 237; }())
+{
+ return i;
+}
+
+int main()
+{
+ if (f(41) != 42)
+ return 1;
+ if (g() != 237)
+ return 2;
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-pass.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-pass.C
new file mode 100644
index 000000000..9dd64484a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-pass.C
@@ -0,0 +1,27 @@
+// { dg-do run }
+// { dg-options "-std=c++0x" }
+
+#include <cassert>
+#include <algorithm>
+
+template <typename F, typename A1>
+void call(F f, const A1& arg1) {
+ f(arg1);
+}
+
+int main() {
+ int i = 1;
+ call(
+ [&i] (int j) -> void { i = j; },
+ 2
+ );
+ assert(i == 2);
+
+ int A[] = {1, 2, 3, 4};
+ int sum = 0;
+ std::for_each(A, A+4, [&sum] (int n) -> void { sum += n; });
+ assert(sum == 10);
+
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-qualified.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-qualified.C
new file mode 100644
index 000000000..ef041c2bb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-qualified.C
@@ -0,0 +1,17 @@
+// PR c++/50089
+// { dg-options -std=c++0x }
+
+struct TestBase
+{
+ void foo() {}
+};
+
+struct Test : TestBase
+{
+ void foo()
+ {
+ [this]{
+ /*this->*/TestBase::foo(); // ICE without this->
+ }();
+ }
+};
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-recursive.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-recursive.C
new file mode 100644
index 000000000..1a12eab31
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-recursive.C
@@ -0,0 +1,21 @@
+// { dg-do run }
+// { dg-options "-std=c++0x" }
+
+//#include <iostream>
+#include <functional>
+#include <cassert>
+
+int main() {
+
+ std::function<int(int)> fib = [&fib] (int n) -> int {
+ //std::cerr << "fib(" << n << ")\n";
+ if (n <= 2) return 1;
+ else return fib(n-1) + fib(n-2);
+ };
+
+ assert(fib(5) == 5);
+ assert(fib(10) == 55);
+
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ref-default.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ref-default.C
new file mode 100644
index 000000000..40376f43d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ref-default.C
@@ -0,0 +1,15 @@
+// { dg-do run }
+// { dg-options "-std=c++0x" }
+
+#include <cassert>
+
+int main() {
+ int i = 1;
+ float j = 2.0;
+ [&] () -> void { i = 3; j = 4.0; } ();
+ assert(i == 3);
+ assert(j == 4.0);
+
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ref.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ref.C
new file mode 100644
index 000000000..a5ee7b4c3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ref.C
@@ -0,0 +1,15 @@
+// { dg-do run }
+// { dg-options "-std=c++0x" }
+
+#include <cassert>
+
+int main() {
+ int i = 1;
+ float j = 2.0;
+ [&i, &j] () -> void { i = 3; j = 4.0; } ();
+ assert(i == 3);
+ assert(j == 4.0);
+
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ref2.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ref2.C
new file mode 100644
index 000000000..15f1d9034
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ref2.C
@@ -0,0 +1,13 @@
+// PR c++/49598
+// { dg-options -std=c++0x }
+// { dg-do run }
+
+int
+main()
+{
+ int i = 10;
+ int& ir = i;
+
+ if ([=]{ return ir; }() != 10)
+ return 1;
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-std-function.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-std-function.C
new file mode 100644
index 000000000..26c09fdb1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-std-function.C
@@ -0,0 +1,22 @@
+// Test using std::function wrapper.
+// { dg-do run }
+// { dg-options -std=c++0x }
+
+#include <functional>
+
+typedef std::function<int()> FN;
+
+template<typename T>
+FN f(T fn)
+{
+ return [fn]{return fn(2);};
+}
+
+int main()
+{
+ auto fn = f([](int i){return i*21;});
+
+ if (fn() != 42)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template.C
new file mode 100644
index 000000000..b4db3b881
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template.C
@@ -0,0 +1,41 @@
+// { dg-options -std=c++0x }
+// { dg-do run }
+
+extern "C" void abort();
+
+template <class T>
+auto apply (T t) -> decltype (t())
+{
+ return t();
+}
+
+template <class T>
+T f(T t)
+{
+ T t2 = t;
+ if (t != [=]()->T { return t; }())
+ abort ();
+ if (t != [=] { return t; }())
+ abort ();
+ if (t != [=] { return t2; }())
+ abort ();
+ if (t != [&] { return t; }())
+ abort ();
+ if (t != apply([=]{return t;}))
+ abort ();
+
+ int i;
+ [&] (int a) { return a+i+t; } (0);
+ [&] (int a) -> decltype(a) { return a+i+t; } (0);
+ [&] (int a) -> decltype(i) { return a+i+t; } (0);
+ [&] (int a) -> decltype(t) { return a+i+t; } (0);
+ [&] (int a) -> decltype(a+i) { return a+i+t; } (0);
+ [&] (int a) -> decltype(a+t) { return a+i+t; } (0);
+ [&] (int a) -> decltype(i+t) { return a+i+t; } (0);
+ [&] (int a) -> decltype(a+i+t) { return a+i+t; } (0);
+}
+
+int main()
+{
+ f(0xbeef);
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template2.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template2.C
new file mode 100644
index 000000000..12ffde724
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template2.C
@@ -0,0 +1,20 @@
+// PR c++/47049
+// { dg-options -std=c++0x }
+
+enum { E = 0, F = 1 };
+template <int N, int M = ((N == 1) ? F : E)> class S {};
+template <int N>
+struct T
+{
+ static void
+ foo (S<N> *p)
+ {
+ S<N> u;
+ [&u] ()->bool {} ();
+ }
+};
+
+int main()
+{
+ T<0>().foo(0);
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this.C
new file mode 100644
index 000000000..ed2747654
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this.C
@@ -0,0 +1,13 @@
+// Test that implicit 'this' capture works, but that it's still an rvalue.
+// { dg-options -std=c++0x }
+
+struct A
+{
+ int i;
+ void f()
+ {
+ [=] { i = 0; };
+ [&] { i = 0; };
+ [=] { this = 0; }; // { dg-error "lvalue" }
+ }
+};
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this2.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this2.C
new file mode 100644
index 000000000..04fe474c7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this2.C
@@ -0,0 +1,17 @@
+// PR c++/43856
+// Test for implicit 'this' capture via rewriting.
+// { dg-options "-std=c++0x" }
+
+struct S1 {
+ int operator()(int);
+ int i;
+ void g();
+ void f() {
+ [=]() {
+ i;
+ g();
+ S1::g();
+ operator()(42);
+ };
+ }
+};
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this3.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this3.C
new file mode 100644
index 000000000..de0d357f3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this3.C
@@ -0,0 +1,14 @@
+// PR c++/45520
+// { dg-options -std=c++0x }
+
+struct M {
+ int i;
+};
+
+struct S {
+ M m;
+
+ void f() {
+ auto lambda=[&](decltype(m.i) & i) { };
+ }
+};
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this4.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this4.C
new file mode 100644
index 000000000..29cd2a97b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this4.C
@@ -0,0 +1,13 @@
+// PR c++/48523
+// { dg-options -std=c++0x }
+
+template<typename>
+struct X
+{
+ bool b;
+
+ void f()
+ {
+ [this]{ return b; };
+ }
+};
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-type.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-type.C
new file mode 100644
index 000000000..3b2a2a76a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-type.C
@@ -0,0 +1,74 @@
+// Every id-expression that is a use (_basic.def.odr_ 3.2) of an entity
+// captured by copy is transformed into an access to the corresponding
+// unnamed data member of the closure type.
+//...
+// Every occurrence of decltype((x)) where x is a possibly parenthesized
+// id-expression that names an entity of automatic storage duration is
+// treated as if x were transformed into an access to a corresponding data
+// member of the closure type that would have been declared if x were a use
+// of the denoted entity.
+
+// So, other appearances of 'x' within decltype do not refer to the closure
+// member, because they are not "use"s in the sense of 3.2.
+
+// { dg-options -std=c++0x }
+
+template<class T, class U>
+struct same_type;
+template <class T>
+struct same_type<T,T> { };
+
+int main()
+{
+ int i;
+ [=] {
+ same_type<decltype(i),int>();
+ same_type<decltype((i)),int const&>();
+ i+1;
+ same_type<decltype((i)),int const&>();
+ same_type<decltype(i),int>();
+ };
+ [=] {
+ same_type<decltype(i),int>();
+ same_type<decltype((i)),int const&>();
+ same_type<decltype(i),int>();
+ };
+ [=] () mutable {
+ same_type<decltype(i),int>();
+ same_type<decltype((i)),int &>();
+ same_type<decltype(i),int>();
+ };
+ [&] {
+ same_type<decltype(i),int>();
+ same_type<decltype((i)),int &>();
+ same_type<decltype(i),int>();
+ };
+ [i] {
+ same_type<decltype(i),int>();
+ same_type<decltype((i)),int const&>();
+ };
+ [&,i] {
+ same_type<decltype(i),int>();
+ same_type<decltype((i)),int const&>();
+ };
+ [i] () mutable {
+ same_type<decltype(i),int>();
+ same_type<decltype((i)),int &>();
+ };
+ [&,i] () mutable {
+ same_type<decltype(i),int>();
+ same_type<decltype((i)),int &>();
+ };
+ [&i] {
+ same_type<decltype(i),int>();
+ same_type<decltype((i)),int &>();
+ };
+ [=,&i] {
+ same_type<decltype(i),int>();
+ same_type<decltype((i)),int &>();
+ };
+ [] {
+ same_type<decltype(i),int>();
+ same_type<decltype((i)),int const&>(); // { dg-error "" "not captured" }
+ };
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-uneval.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-uneval.C
new file mode 100644
index 000000000..33ba7b0a4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-uneval.C
@@ -0,0 +1,7 @@
+// 5.1.2/2: A lambda-expression shall not appear in an unevaluated operand.
+// { dg-options "-std=c++0x" }
+
+template <class T>
+struct A { };
+A<decltype([]{ return 1; }())> a; // { dg-error "lambda.*unevaluated context" }
+
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-use.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-use.C
new file mode 100644
index 000000000..b1d6c300c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-use.C
@@ -0,0 +1,12 @@
+// { dg-options -std=c++0x }
+
+int main(int argc, char** argv)
+{
+ int i;
+ int &ir = i;
+ const int ci = 0;
+ const int &cir = ci;
+
+ [] { sizeof (argc); sizeof (i); sizeof (ir); sizeof (ci); sizeof (cir); };
+ [] { int ia[ci]; };
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-use2.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-use2.C
new file mode 100644
index 000000000..695a0b432
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-use2.C
@@ -0,0 +1,11 @@
+// PR c++/50224
+// { dg-options "-std=c++0x -Wunused-parameter" }
+
+struct T;
+
+void m(T& t) // ERROR here
+{
+ [&]{
+ t; // ``t`` is referenced here
+ };
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic1.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic1.C
new file mode 100644
index 000000000..f17b33618
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic1.C
@@ -0,0 +1,15 @@
+// PR c++/49672
+// { dg-options -std=c++0x }
+
+template<typename ... Args>
+static void foo()
+{
+ [](Args..., int x) {
+ x;
+ };
+}
+
+int main()
+{
+ foo();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-warn1.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-warn1.C
new file mode 100644
index 000000000..b384d5cff
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-warn1.C
@@ -0,0 +1,8 @@
+// PR c++/41920
+// { dg-options "-std=c++0x -Wall -Wextra" }
+
+int foo(int i)
+{
+ auto bar = [=](){ return i; };
+ return bar();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-warn2.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-warn2.C
new file mode 100644
index 000000000..ce5e7c450
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-warn2.C
@@ -0,0 +1,7 @@
+// PR c++/42370
+// { dg-options "-std=c++0x -Wall" }
+
+void foo()
+{
+ []{ return 0; }();
+} // { dg-bogus "no return statement" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-warn3.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-warn3.C
new file mode 100644
index 000000000..77f35bc46
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-warn3.C
@@ -0,0 +1,12 @@
+// PR c++/49482
+// { dg-options "-std=c++0x -Wunused-but-set-parameter" }
+
+template<class T>
+void f() {
+ []( bool b ){ return b; };
+}
+
+int main()
+{
+ f<int>();
+}