Clang Project

clang_source_code/test/SemaCXX/cxx1z-lambda-star-this.cpp
1// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -emit-llvm-only %s
2// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s -DDELAYED_TEMPLATE_PARSING
3// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fms-extensions %s -DMS_EXTENSIONS
4// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing -fms-extensions %s -DMS_EXTENSIONS -DDELAYED_TEMPLATE_PARSING
5
6template <class, class>
7constexpr bool is_same = false;
8template <class T>
9constexpr bool is_same<T, T> = true;
10
11namespace test_star_this {
12namespace ns1 {
13class A {
14  int x = 345;
15  auto foo() {
16    (void)[ *this, this ]{}; //expected-error{{'this' can appear only once}}
17    (void)[this] { ++x; };
18    (void)[*this] { ++x; }; //expected-error{{read-only variable}}
19    (void)[*this]() mutable { ++x; };
20    (void)[=] { return x; };
21    (void)[&, this ] { return x; };
22    (void)[ =, *this ] { return x; };
23    (void)[&, *this ] { return x; };
24  }
25};
26} // namespace ns1
27
28namespace ns2 {
29class B {
30  B(const B &) = delete; //expected-note{{deleted here}}
31  int *x = (int *)456;
32  void foo() {
33    (void)[this] { return x; };
34    (void)[*this] { return x; }; //expected-error{{call to deleted}}
35  }
36};
37} // namespace ns2
38
39namespace ns3 {
40class B {
41  B(const B &) = delete; //expected-note2{{deleted here}}
42
43  int *x = (int *)456;
44
45public:
46  template <class T = int>
47  void foo() {
48    (void)[this] { return x; };
49    (void)[*this] { return x; }; //expected-error2{{call to deleted}}
50  }
51
52  B() = default;
53} b;
54B *c = (b.foo(), nullptr); //expected-note{{in instantiation}}
55} // namespace ns3
56
57namespace ns4 {
58template <class U>
59class B {
60  B(const B &) = delete; //expected-note{{deleted here}}
61  double d = 3.14;
62
63public:
64  template <class T = int>
65  auto foo() {
66    const auto &L = [*this](auto a) mutable { //expected-error{{call to deleted}}
67      d += a;
68      return [this](auto b) { return d += b; };
69    };
70  }
71
72  B() = default;
73};
74void main() {
75  B<int *> b;
76  b.foo(); //expected-note{{in instantiation}}
77} // end main
78} // namespace ns4
79
80namespace ns5 {
81
82struct X {
83  double d = 3.14;
84  X(const volatile X &);
85  void foo() {
86  }
87
88  void foo() const { //expected-note{{const}}
89
90    auto L = [*this]() mutable {
91      static_assert(is_same<decltype(this), X *>);
92      ++d;
93      auto M = [this] {
94        static_assert(is_same<decltype(this), X *>);
95        ++d;
96        auto N = [] {
97          static_assert(is_same<decltype(this), X *>);
98        };
99      };
100    };
101
102    auto L1 = [*this] {
103      static_assert(is_same<decltype(this), const X *>);
104      auto M = [this]() mutable {
105        static_assert(is_same<decltype(this), const X *>);
106        auto N = [] {
107          static_assert(is_same<decltype(this), const X *>);
108        };
109      };
110      auto M2 = [*this]() mutable {
111        static_assert(is_same<decltype(this), X *>);
112        auto N = [] {
113          static_assert(is_same<decltype(this), X *>);
114        };
115      };
116    };
117
118    auto GL1 = [*this](auto a) {
119      static_assert(is_same<decltype(this), const X *>);
120      auto M = [this](auto b) mutable {
121        static_assert(is_same<decltype(this), const X *>);
122        auto N = [](auto c) {
123          static_assert(is_same<decltype(this), const X *>);
124        };
125        return N;
126      };
127
128      auto M2 = [*this](auto a) mutable {
129        static_assert(is_same<decltype(this), X *>);
130        auto N = [](auto b) {
131          static_assert(is_same<decltype(this), X *>);
132        };
133        return N;
134      };
135      return [=](auto a) mutable { M(a)(a); M2(a)(a); };
136    };
137
138    GL1("abc")
139    ("abc");
140
141    auto L2 = [this]() mutable {
142      static_assert(is_same<decltype(this), const X *>);
143      ++d; //expected-error{{cannot assign}}
144    };
145    auto GL = [*this](auto a) mutable {
146      static_assert(is_same<decltype(this), X *>);
147      ++d;
148      auto M = [this](auto b) {
149        static_assert(is_same<decltype(this), X *>);
150        ++d;
151        auto N = [](auto c) {
152          static_assert(is_same<decltype(this), X *>);
153        };
154        N(3.14);
155      };
156      M("abc");
157    };
158    GL(3.14);
159  }
160  void foo() volatile const {
161    auto L = [this]() {
162      static_assert(is_same<decltype(this), const volatile X *>);
163      auto M = [*this]() mutable {
164        static_assert(is_same<decltype(this), X *>);
165        auto N = [this] {
166          static_assert(is_same<decltype(this), X *>);
167          auto M = [] {
168            static_assert(is_same<decltype(this), X *>);
169          };
170        };
171        auto N2 = [*this] {
172          static_assert(is_same<decltype(this), const X *>);
173        };
174      };
175      auto M2 = [*this]() {
176        static_assert(is_same<decltype(this), const X *>);
177        auto N = [this] {
178          static_assert(is_same<decltype(this), const X *>);
179        };
180      };
181    };
182  }
183};
184
185} // namespace ns5
186namespace ns6 {
187struct X {
188  double d;
189  auto foo() const {
190    auto L = [*this]() mutable {
191      auto M = [=](auto a) {
192        auto N = [this] {
193          ++d;
194          static_assert(is_same<decltype(this), X *>);
195          auto O = [*this] {
196            static_assert(is_same<decltype(this), const X *>);
197          };
198        };
199        N();
200        static_assert(is_same<decltype(this), X *>);
201      };
202      return M;
203    };
204    return L;
205  }
206};
207
208int main() {
209  auto L = X{}.foo();
210  auto M = L();
211  M(3.14);
212}
213} // namespace ns6
214namespace ns7 {
215
216struct X {
217  double d;
218  X();
219  X(const X &);
220  X(X &) = delete;
221  auto foo() const {
222    //OK - the object used to initialize our capture is a const object and so prefers the non-deleted ctor.
223    const auto &&L = [*this]{};
224  }
225};
226int main() {
227  X x;
228  x.foo();
229}
230} // namespace ns7
231
232} // namespace test_star_this
233
234namespace PR32831 {
235// https://bugs.llvm.org/show_bug.cgi?id=32831
236namespace ns1 {
237template <typename Func>
238void fun_template(Func func) {
239  (void)[&]() {
240    func(0);
241  };
242}
243
244class A {
245  void member_foo() {
246    (void)[this] {
247      (void)[this] {
248        fun_template(
249            [this](auto X) {
250              auto L = [this](auto Y) { member_foo(); };
251              L(5);
252            });
253        fun_template(
254            [this](auto) { member_foo(); });
255      };
256    };
257  }
258};
259} // namespace ns1
260
261namespace ns2 {
262
263struct B {
264  int data = 0;
265  template <class F>
266  void mem2(F f) {
267    (void)[&](auto f) {
268      (void)[&] { f(this->data); };
269    }
270    (f);
271  }
272};
273
274class A {
275  void member_foo() {
276    (void)[this] {
277      (void)[this] {
278        B{}.mem2(
279            [this](auto X) {
280              auto L = [this](auto Y) { member_foo(); };
281              L(5);
282            });
283        B{}.mem2(
284            [this](auto) { member_foo(); });
285      };
286    };
287  }
288  int data = 0;
289  auto m2() {
290    return [this] { return [] () -> decltype(data){ return 0; }; };
291  }
292  auto m3() {
293    return [] { return [] () -> decltype(data){ return 0; }; };
294  }
295};
296
297} // namespace ns2
298
299} // namespace PR32831
300
301