diff options
Diffstat (limited to 'clang/test/SemaCXX/cxx1z-lambda-star-this.cpp')
-rw-r--r-- | clang/test/SemaCXX/cxx1z-lambda-star-this.cpp | 531 |
1 files changed, 300 insertions, 231 deletions
diff --git a/clang/test/SemaCXX/cxx1z-lambda-star-this.cpp b/clang/test/SemaCXX/cxx1z-lambda-star-this.cpp index a84e653f5c8..2426e8f5a20 100644 --- a/clang/test/SemaCXX/cxx1z-lambda-star-this.cpp +++ b/clang/test/SemaCXX/cxx1z-lambda-star-this.cpp @@ -1,231 +1,300 @@ -// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -emit-llvm-only %s
-// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s -DDELAYED_TEMPLATE_PARSING
-// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fms-extensions %s -DMS_EXTENSIONS
-// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing -fms-extensions %s -DMS_EXTENSIONS -DDELAYED_TEMPLATE_PARSING
-
-template<class, class> constexpr bool is_same = false;
-template<class T> constexpr bool is_same<T, T> = true;
-
-namespace test_star_this {
-namespace ns1 {
-class A {
- int x = 345;
- auto foo() {
- (void) [*this, this] { }; //expected-error{{'this' can appear only once}}
- (void) [this] { ++x; };
- (void) [*this] { ++x; }; //expected-error{{read-only variable}}
- (void) [*this] () mutable { ++x; };
- (void) [=] { return x; };
- (void) [&, this] { return x; };
- (void) [=, *this] { return x; };
- (void) [&, *this] { return x; };
- }
-};
-} // end ns1
-
-namespace ns2 {
- class B {
- B(const B&) = delete; //expected-note{{deleted here}}
- int *x = (int *) 456;
- void foo() {
- (void)[this] { return x; };
- (void)[*this] { return x; }; //expected-error{{call to deleted}}
- }
- };
-} // end ns2
-namespace ns3 {
- class B {
- B(const B&) = delete; //expected-note2{{deleted here}}
-
- int *x = (int *) 456;
- public:
- template<class T = int>
- void foo() {
- (void)[this] { return x; };
- (void)[*this] { return x; }; //expected-error2{{call to deleted}}
- }
-
- B() = default;
- } b;
- B *c = (b.foo(), nullptr); //expected-note{{in instantiation}}
-} // end ns3
-
-namespace ns4 {
-template<class U>
-class B {
- B(const B&) = delete; //expected-note{{deleted here}}
- double d = 3.14;
- public:
- template<class T = int>
- auto foo() {
- const auto &L = [*this] (auto a) mutable { //expected-error{{call to deleted}}
- d += a;
- return [this] (auto b) { return d +=b; };
- };
- }
-
- B() = default;
-};
-void main() {
- B<int*> b;
- b.foo(); //expected-note{{in instantiation}}
-} // end main
-} // end ns4
-namespace ns5 {
-
-struct X {
- double d = 3.14;
- X(const volatile X&);
- void foo() {
-
- }
-
- void foo() const { //expected-note{{const}}
-
- auto L = [*this] () mutable {
- static_assert(is_same<decltype(this), X*>);
- ++d;
- auto M = [this] {
- static_assert(is_same<decltype(this), X*>);
- ++d;
- auto N = [] {
- static_assert(is_same<decltype(this), X*>);
- };
- };
- };
-
- auto L1 = [*this] {
- static_assert(is_same<decltype(this), const X*>);
- auto M = [this] () mutable {
- static_assert(is_same<decltype(this), const X*>);
- auto N = [] {
- static_assert(is_same<decltype(this), const X*>);
- };
- };
- auto M2 = [*this] () mutable {
- static_assert(is_same<decltype(this), X*>);
- auto N = [] {
- static_assert(is_same<decltype(this), X*>);
- };
- };
- };
-
- auto GL1 = [*this] (auto a) {
- static_assert(is_same<decltype(this), const X*>);
- auto M = [this] (auto b) mutable {
- static_assert(is_same<decltype(this), const X*>);
- auto N = [] (auto c) {
- static_assert(is_same<decltype(this), const X*>);
- };
- return N;
- };
-
- auto M2 = [*this] (auto a) mutable {
- static_assert(is_same<decltype(this), X*>);
- auto N = [] (auto b) {
- static_assert(is_same<decltype(this), X*>);
- };
- return N;
- };
- return [=](auto a) mutable { M(a)(a); M2(a)(a); };
- };
-
- GL1("abc")("abc");
-
-
- auto L2 = [this] () mutable {
- static_assert(is_same<decltype(this), const X*>);
- ++d; //expected-error{{cannot assign}}
- };
- auto GL = [*this] (auto a) mutable {
- static_assert(is_same<decltype(this), X*>);
- ++d;
- auto M = [this] (auto b) {
- static_assert(is_same<decltype(this), X*>);
- ++d;
- auto N = [] (auto c) {
- static_assert(is_same<decltype(this), X*>);
- };
- N(3.14);
- };
- M("abc");
- };
- GL(3.14);
-
- }
- void foo() volatile const {
- auto L = [this] () {
- static_assert(is_same<decltype(this), const volatile X*>);
- auto M = [*this] () mutable {
- static_assert(is_same<decltype(this), X*>);
- auto N = [this] {
- static_assert(is_same<decltype(this), X*>);
- auto M = [] {
- static_assert(is_same<decltype(this), X*>);
- };
- };
- auto N2 = [*this] {
- static_assert(is_same<decltype(this), const X*>);
- };
- };
- auto M2 = [*this] () {
- static_assert(is_same<decltype(this), const X*>);
- auto N = [this] {
- static_assert(is_same<decltype(this), const X*>);
- };
- };
- };
- }
-
-};
-
-} //end ns5
-namespace ns6 {
-struct X {
- double d;
- auto foo() const {
- auto L = [*this] () mutable {
- auto M = [=] (auto a) {
- auto N = [this] {
- ++d;
- static_assert(is_same<decltype(this), X*>);
- auto O = [*this] {
- static_assert(is_same<decltype(this), const X*>);
- };
- };
- N();
- static_assert(is_same<decltype(this), X*>);
- };
- return M;
- };
- return L;
- }
-};
-
-int main() {
- auto L = X{}.foo();
- auto M = L();
- M(3.14);
-}
-} // end ns6
-namespace ns7 {
-
-struct X {
- double d;
- X();
- X(const X&);
- X(X&) = delete;
- auto foo() const {
- //OK - the object used to initialize our capture is a const object and so prefers the non-deleted ctor.
- const auto &&L = [*this] { };
- }
-
-};
-int main() {
- X x;
- x.foo();
-}
-} // end ns7
-
-} //end ns test_star_this
-
+// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -emit-llvm-only %s +// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s -DDELAYED_TEMPLATE_PARSING +// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fms-extensions %s -DMS_EXTENSIONS +// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing -fms-extensions %s -DMS_EXTENSIONS -DDELAYED_TEMPLATE_PARSING + +template <class, class> +constexpr bool is_same = false; +template <class T> +constexpr bool is_same<T, T> = true; + +namespace test_star_this { +namespace ns1 { +class A { + int x = 345; + auto foo() { + (void)[ *this, this ]{}; //expected-error{{'this' can appear only once}} + (void)[this] { ++x; }; + (void)[*this] { ++x; }; //expected-error{{read-only variable}} + (void)[*this]() mutable { ++x; }; + (void)[=] { return x; }; + (void)[&, this ] { return x; }; + (void)[ =, *this ] { return x; }; + (void)[&, *this ] { return x; }; + } +}; +} // namespace ns1 + +namespace ns2 { +class B { + B(const B &) = delete; //expected-note{{deleted here}} + int *x = (int *)456; + void foo() { + (void)[this] { return x; }; + (void)[*this] { return x; }; //expected-error{{call to deleted}} + } +}; +} // namespace ns2 + +namespace ns3 { +class B { + B(const B &) = delete; //expected-note2{{deleted here}} + + int *x = (int *)456; + +public: + template <class T = int> + void foo() { + (void)[this] { return x; }; + (void)[*this] { return x; }; //expected-error2{{call to deleted}} + } + + B() = default; +} b; +B *c = (b.foo(), nullptr); //expected-note{{in instantiation}} +} // namespace ns3 + +namespace ns4 { +template <class U> +class B { + B(const B &) = delete; //expected-note{{deleted here}} + double d = 3.14; + +public: + template <class T = int> + auto foo() { + const auto &L = [*this](auto a) mutable { //expected-error{{call to deleted}} + d += a; + return [this](auto b) { return d += b; }; + }; + } + + B() = default; +}; +void main() { + B<int *> b; + b.foo(); //expected-note{{in instantiation}} +} // end main +} // namespace ns4 + +namespace ns5 { + +struct X { + double d = 3.14; + X(const volatile X &); + void foo() { + } + + void foo() const { //expected-note{{const}} + + auto L = [*this]() mutable { + static_assert(is_same<decltype(this), X *>); + ++d; + auto M = [this] { + static_assert(is_same<decltype(this), X *>); + ++d; + auto N = [] { + static_assert(is_same<decltype(this), X *>); + }; + }; + }; + + auto L1 = [*this] { + static_assert(is_same<decltype(this), const X *>); + auto M = [this]() mutable { + static_assert(is_same<decltype(this), const X *>); + auto N = [] { + static_assert(is_same<decltype(this), const X *>); + }; + }; + auto M2 = [*this]() mutable { + static_assert(is_same<decltype(this), X *>); + auto N = [] { + static_assert(is_same<decltype(this), X *>); + }; + }; + }; + + auto GL1 = [*this](auto a) { + static_assert(is_same<decltype(this), const X *>); + auto M = [this](auto b) mutable { + static_assert(is_same<decltype(this), const X *>); + auto N = [](auto c) { + static_assert(is_same<decltype(this), const X *>); + }; + return N; + }; + + auto M2 = [*this](auto a) mutable { + static_assert(is_same<decltype(this), X *>); + auto N = [](auto b) { + static_assert(is_same<decltype(this), X *>); + }; + return N; + }; + return [=](auto a) mutable { M(a)(a); M2(a)(a); }; + }; + + GL1("abc") + ("abc"); + + auto L2 = [this]() mutable { + static_assert(is_same<decltype(this), const X *>); + ++d; //expected-error{{cannot assign}} + }; + auto GL = [*this](auto a) mutable { + static_assert(is_same<decltype(this), X *>); + ++d; + auto M = [this](auto b) { + static_assert(is_same<decltype(this), X *>); + ++d; + auto N = [](auto c) { + static_assert(is_same<decltype(this), X *>); + }; + N(3.14); + }; + M("abc"); + }; + GL(3.14); + } + void foo() volatile const { + auto L = [this]() { + static_assert(is_same<decltype(this), const volatile X *>); + auto M = [*this]() mutable { + static_assert(is_same<decltype(this), X *>); + auto N = [this] { + static_assert(is_same<decltype(this), X *>); + auto M = [] { + static_assert(is_same<decltype(this), X *>); + }; + }; + auto N2 = [*this] { + static_assert(is_same<decltype(this), const X *>); + }; + }; + auto M2 = [*this]() { + static_assert(is_same<decltype(this), const X *>); + auto N = [this] { + static_assert(is_same<decltype(this), const X *>); + }; + }; + }; + } +}; + +} // namespace ns5 +namespace ns6 { +struct X { + double d; + auto foo() const { + auto L = [*this]() mutable { + auto M = [=](auto a) { + auto N = [this] { + ++d; + static_assert(is_same<decltype(this), X *>); + auto O = [*this] { + static_assert(is_same<decltype(this), const X *>); + }; + }; + N(); + static_assert(is_same<decltype(this), X *>); + }; + return M; + }; + return L; + } +}; + +int main() { + auto L = X{}.foo(); + auto M = L(); + M(3.14); +} +} // namespace ns6 +namespace ns7 { + +struct X { + double d; + X(); + X(const X &); + X(X &) = delete; + auto foo() const { + //OK - the object used to initialize our capture is a const object and so prefers the non-deleted ctor. + const auto &&L = [*this]{}; + } +}; +int main() { + X x; + x.foo(); +} +} // namespace ns7 + +} // namespace test_star_this + +namespace PR32831 { +// https://bugs.llvm.org/show_bug.cgi?id=32831 +namespace ns1 { +template <typename Func> +void fun_template(Func func) { + (void)[&]() { + func(0); + }; +} + +class A { + void member_foo() { + (void)[this] { + (void)[this] { + fun_template( + [this](auto X) { + auto L = [this](auto Y) { member_foo(); }; + L(5); + }); + fun_template( + [this](auto) { member_foo(); }); + }; + }; + } +}; +} // namespace ns1 + +namespace ns2 { + +struct B { + int data = 0; + template <class F> + void mem2(F f) { + (void)[&](auto f) { + (void)[&] { f(this->data); }; + } + (f); + } +}; + +class A { + void member_foo() { + (void)[this] { + (void)[this] { + B{}.mem2( + [this](auto X) { + auto L = [this](auto Y) { member_foo(); }; + L(5); + }); + B{}.mem2( + [this](auto) { member_foo(); }); + }; + }; + } + int data = 0; + auto m2() { + return [this] { return [] () -> decltype(data){ return 0; }; }; + } + auto m3() { + return [] { return [] () -> decltype(data){ return 0; }; }; + } +}; + +} // namespace ns2 + +} // namespace PR32831 + |