From 554fd8c5195424bdbcabf5de30fdc183aba391bd Mon Sep 17 00:00:00 2001 From: upstream source tree Date: Sun, 15 Mar 2015 20:14:05 -0400 Subject: obtained gcc-4.6.4.tar.bz2 from upstream website; 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. --- gcc/testsuite/g++.dg/cpp0x/lambda/lambda-50220.C | 9 ++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-98.C | 8 ++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-array.C | 20 ++++ .../cpp0x/lambda/lambda-capture-const-ref-neg.C | 14 +++ .../g++.dg/cpp0x/lambda/lambda-capture-const-ref.C | 15 +++ .../g++.dg/cpp0x/lambda/lambda-const-neg.C | 19 ++++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const.C | 20 ++++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv.C | 14 +++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv2.C | 12 +++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv3.C | 12 +++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv4.C | 13 +++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv5.C | 15 +++ .../g++.dg/cpp0x/lambda/lambda-copy-default-neg.C | 13 +++ .../g++.dg/cpp0x/lambda/lambda-copy-default.C | 14 +++ .../g++.dg/cpp0x/lambda/lambda-copy-neg.C | 13 +++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-copy.C | 14 +++ .../g++.dg/cpp0x/lambda/lambda-ctor-neg.C | 25 +++++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ctors.C | 18 ++++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-debug.C | 15 +++ .../g++.dg/cpp0x/lambda/lambda-deduce-ext-neg.C | 24 +++++ .../g++.dg/cpp0x/lambda/lambda-deduce-ext-neg2.C | 22 +++++ .../g++.dg/cpp0x/lambda/lambda-deduce-ext.C | 27 ++++++ .../g++.dg/cpp0x/lambda/lambda-deduce-neg.C | 10 ++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce.C | 29 ++++++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce2.C | 7 ++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-defarg.C | 6 ++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-defarg2.C | 7 ++ .../g++.dg/cpp0x/lambda/lambda-direct-init.C | 14 +++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-eh.C | 35 +++++++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-eh2.C | 17 ++++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-errloc.C | 18 ++++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-errloc2.C | 19 ++++ .../g++.dg/cpp0x/lambda/lambda-field-names.C | 21 +++++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice1.C | 13 +++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice2.C | 16 ++++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice3.C | 23 +++++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice4.C | 14 +++ .../g++.dg/cpp0x/lambda/lambda-in-class-neg.C | 35 +++++++ .../g++.dg/cpp0x/lambda/lambda-in-class.C | 36 +++++++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-init.C | 8 ++ .../g++.dg/cpp0x/lambda/lambda-lookup-neg.C | 7 ++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mangle.C | 103 +++++++++++++++++++++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mangle2.C | 21 +++++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mixed.C | 13 +++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mutable.C | 16 ++++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested.C | 63 +++++++++++++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested2.C | 31 +++++++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested3.C | 12 +++ .../g++.dg/cpp0x/lambda/lambda-non-const.C | 19 ++++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nop.C | 19 ++++ .../g++.dg/cpp0x/lambda/lambda-ns-scope.C | 18 ++++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-pass.C | 27 ++++++ .../g++.dg/cpp0x/lambda/lambda-qualified.C | 17 ++++ .../g++.dg/cpp0x/lambda/lambda-recursive.C | 21 +++++ .../g++.dg/cpp0x/lambda/lambda-ref-default.C | 15 +++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ref.C | 15 +++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ref2.C | 13 +++ .../g++.dg/cpp0x/lambda/lambda-std-function.C | 22 +++++ .../g++.dg/cpp0x/lambda/lambda-template.C | 41 ++++++++ .../g++.dg/cpp0x/lambda/lambda-template2.C | 20 ++++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this.C | 13 +++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this2.C | 17 ++++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this3.C | 14 +++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this4.C | 13 +++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-type.C | 74 +++++++++++++++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-uneval.C | 7 ++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-use.C | 12 +++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-use2.C | 11 +++ .../g++.dg/cpp0x/lambda/lambda-variadic1.C | 15 +++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-warn1.C | 8 ++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-warn2.C | 7 ++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-warn3.C | 12 +++ 72 files changed, 1400 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-50220.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-98.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-array.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-capture-const-ref-neg.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-capture-const-ref.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const-neg.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv2.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv3.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv4.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv5.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-copy-default-neg.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-copy-default.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-copy-neg.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-copy.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ctor-neg.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ctors.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-debug.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce-ext-neg.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce-ext-neg2.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce-ext.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce-neg.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce2.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-defarg.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-defarg2.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-direct-init.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-eh.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-eh2.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-errloc.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-errloc2.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-field-names.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice1.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice2.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice3.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice4.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-in-class-neg.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-in-class.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-init.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-lookup-neg.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mangle.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mangle2.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mixed.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mutable.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested2.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested3.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-non-const.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nop.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ns-scope.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-pass.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-qualified.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-recursive.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ref-default.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ref.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ref2.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-std-function.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template2.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this2.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this3.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this4.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-type.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-uneval.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-use.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-use2.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic1.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-warn1.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-warn2.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-warn3.C (limited to 'gcc/testsuite/g++.dg/cpp0x/lambda') 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 struct Foobar {}; + +void foobar(const Foobar& 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 + +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 + +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 + +template +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 + +template +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 +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 +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 +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 +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 +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 + +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 + +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 + +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 +void f() +{ + T t; + [t] { return 0; }; // { dg-error "use" } +} + +int main() +{ + f(); // { 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 +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 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 +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(); +} 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 + +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 + +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 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 + // and so this closure type has the same 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 struct R { + static int x; +}; +template int R::x = []{return 1;}(); +template int R::x; +// Type of lambda in intializer of R::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 +void fn2 (T t = []{return 1;}()) {} + +int main() +{ + g(42); + S().f(); + function(); + Foo().Bar(); + fn2(); +} 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 +struct F +{ + template 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 + +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 + +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 + +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 + +template +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 + +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 +#include + +template +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 +#include +#include + +int main() { + + std::function 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 + +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 + +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 + +typedef std::function FN; + +template +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 +auto apply (T t) -> decltype (t()) +{ + return t(); +} + +template +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 class S {}; +template +struct T +{ + static void + foo (S *p) + { + S 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 +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 +struct same_type; +template +struct same_type { }; + +int main() +{ + int i; + [=] { + same_type(); + same_type(); + i+1; + same_type(); + same_type(); + }; + [=] { + same_type(); + same_type(); + same_type(); + }; + [=] () mutable { + same_type(); + same_type(); + same_type(); + }; + [&] { + same_type(); + same_type(); + same_type(); + }; + [i] { + same_type(); + same_type(); + }; + [&,i] { + same_type(); + same_type(); + }; + [i] () mutable { + same_type(); + same_type(); + }; + [&,i] () mutable { + same_type(); + same_type(); + }; + [&i] { + same_type(); + same_type(); + }; + [=,&i] { + same_type(); + same_type(); + }; + [] { + same_type(); + same_type(); // { 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 +struct A { }; +A 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 +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 +void f() { + []( bool b ){ return b; }; +} + +int main() +{ + f(); +} -- cgit v1.2.3