xref: /llvm-project/clang/test/SemaCXX/cxx1z-lambda-star-this.cpp (revision 7c1d9b15eee3a34678addab2bab66f3020ac0753)
1 // RUN: %clang_cc1 -std=c++1z -verify -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 
6 // RUN: %clang_cc1 -std=c++1z -verify -fblocks -emit-llvm-only %s -fexperimental-new-constant-interpreter
7 // RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s -DDELAYED_TEMPLATE_PARSING -fexperimental-new-constant-interpreter
8 // RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fms-extensions %s -DMS_EXTENSIONS -fexperimental-new-constant-interpreter
9 // RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing -fms-extensions %s -DMS_EXTENSIONS -DDELAYED_TEMPLATE_PARSING -fexperimental-new-constant-interpreter
10 
11 template <class, class>
12 constexpr bool is_same = false;
13 template <class T>
14 constexpr bool is_same<T, T> = true;
15 
16 namespace test_star_this {
17 namespace ns1 {
18 class A {
19   int x = 345;
foo()20   auto foo() {
21     (void)[ *this, this ]{}; //expected-error{{'this' can appear only once}}
22     (void)[this] { ++x; };
23     (void)[*this] { ++x; }; //expected-error{{read-only variable}}
24     (void)[*this]() mutable { ++x; };
25     (void)[=] { return x; };
26     (void)[&, this ] { return x; };
27     (void)[ =, *this ] { return x; };
28     (void)[&, *this ] { return x; };
29   }
30 };
31 } // namespace ns1
32 
33 namespace ns2 {
34 class B {
35   B(const B &) = delete; //expected-note{{deleted here}}
36   int *x = (int *)456;
foo()37   void foo() {
38     (void)[this] { return x; };
39     (void)[*this] { return x; }; //expected-error{{call to deleted}}
40   }
41 };
42 } // namespace ns2
43 
44 namespace ns3 {
45 class B {
46   B(const B &) = delete; //expected-note2{{deleted here}}
47 
48   int *x = (int *)456;
49 
50 public:
51   template <class T = int>
foo()52   void foo() {
53     (void)[this] { return x; };
54     (void)[*this] { return x; }; //expected-error2{{call to deleted}}
55   }
56 
57   B() = default;
58 } b;
59 B *c = (b.foo(), nullptr); //expected-note{{in instantiation}}
60 } // namespace ns3
61 
62 namespace ns4 {
63 template <class U>
64 class B {
65   B(const B &) = delete; //expected-note{{deleted here}}
66   double d = 3.14;
67 
68 public:
69   template <class T = int>
foo()70   auto foo() {
71     const auto &L = [*this](auto a) mutable { //expected-error{{call to deleted}}
72       d += a;
73       return [this](auto b) { return d += b; };
74     };
75   }
76 
77   B() = default;
78 };
main()79 void main() {
80   B<int *> b;
81   b.foo(); //expected-note{{in instantiation}}
82 } // end main
83 } // namespace ns4
84 
85 namespace ns5 {
86 
87 struct X {
88   double d = 3.14;
89   X(const volatile X &);
footest_star_this::ns5::X90   void foo() {
91   }
92 
footest_star_this::ns5::X93   void foo() const { //expected-note{{const}}
94 
95     auto L = [*this]() mutable {
96       static_assert(is_same<decltype(this), const X *>);
97       auto M = [this] {
98         static_assert(is_same<decltype(this), const X *>);
99         auto N = [] {
100           static_assert(is_same<decltype(this), const X *>);
101         };
102       };
103     };
104 
105     auto L1 = [*this] {
106       static_assert(is_same<decltype(this), const X *>);
107       auto M = [this]() mutable {
108         static_assert(is_same<decltype(this), const X *>);
109         auto N = [] {
110           static_assert(is_same<decltype(this), const X *>);
111         };
112       };
113       auto M2 = [*this]() mutable {
114         static_assert(is_same<decltype(this), const X *>);
115         auto N = [] {
116           static_assert(is_same<decltype(this), const X *>);
117         };
118       };
119     };
120 
121     auto GL1 = [*this](auto a) {
122       static_assert(is_same<decltype(this), const X *>);
123       auto M = [this](auto b) mutable {
124         static_assert(is_same<decltype(this), const X *>);
125         auto N = [](auto c) {
126           static_assert(is_same<decltype(this), const X *>);
127         };
128         return N;
129       };
130 
131       auto M2 = [*this](auto a) mutable {
132         static_assert(is_same<decltype(this), const X *>);
133         auto N = [](auto b) {
134           static_assert(is_same<decltype(this), const X *>);
135         };
136         return N;
137       };
138       return [=](auto a) mutable { M(a)(a); M2(a)(a); };
139     };
140 
141     GL1("abc")
142     ("abc");
143 
144     auto L2 = [this]() mutable {
145       static_assert(is_same<decltype(this), const X *>);
146       ++d; //expected-error{{cannot assign}}
147     };
148     auto GL = [*this](auto a) mutable {
149       static_assert(is_same<decltype(this), const X *>);
150       auto M = [this](auto b) {
151         static_assert(is_same<decltype(this), const X *>);
152         auto N = [](auto c) {
153           static_assert(is_same<decltype(this), const X *>);
154         };
155         N(3.14);
156       };
157       M("abc");
158     };
159     GL(3.14);
160   }
footest_star_this::ns5::X161   void foo() volatile const {
162     auto L = [this]() {
163       static_assert(is_same<decltype(this), const volatile X *>);
164       auto M = [*this]() mutable {
165         static_assert(is_same<decltype(this), const volatile X *>);
166         auto N = [this] {
167           static_assert(is_same<decltype(this), const volatile X *>);
168           auto M = [] {
169             static_assert(is_same<decltype(this), const volatile X *>);
170           };
171         };
172         auto N2 = [*this] {
173           static_assert(is_same<decltype(this), const volatile X *>);
174         };
175       };
176       auto M2 = [*this]() {
177         static_assert(is_same<decltype(this), const volatile X *>);
178         auto N = [this] {
179           static_assert(is_same<decltype(this), const volatile X *>);
180         };
181       };
182     };
183   }
184 };
185 
186 } // namespace ns5
187 namespace ns6 {
188 struct X {
189   double d;
footest_star_this::ns6::X190   auto foo() const {
191     auto L = [*this]() mutable {
192       auto M = [=](auto a) {
193         auto N = [this] {
194           static_assert(is_same<decltype(this), const 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), const X *>);
201       };
202       return M;
203     };
204     return L;
205   }
206 };
207 
main()208 int main() {
209   auto L = X{}.foo();
210   auto M = L();
211   M(3.14);
212 }
213 } // namespace ns6
214 namespace ns7 {
215 
216 struct X {
217   double d;
218   X();
219   X(const X &);
220   X(X &) = delete;
footest_star_this::ns7::X221   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 };
main()226 int main() {
227   X x;
228   x.foo();
229 }
230 } // namespace ns7
231 
232 } // namespace test_star_this
233 
234 namespace PR32831 {
235 // https://bugs.llvm.org/show_bug.cgi?id=32831
236 namespace ns1 {
237 template <typename Func>
fun_template(Func func)238 void fun_template(Func func) {
239   (void)[&]() {
240     func(0);
241   };
242 }
243 
244 class A {
member_foo()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 
261 namespace ns2 {
262 
263 struct B {
264   int data = 0;
265   template <class F>
mem2PR32831::ns2::B266   void mem2(F f) {
267     (void)[&](auto f) {
268       (void)[&] { f(this->data); };
269     }
270     (f);
271   }
272 };
273 
274 class A {
member_foo()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;
m2()289   auto m2() {
290     return [this] { return [] () -> decltype(data){ return 0; }; };
291   }
m3()292   auto m3() {
293     return [] { return [] () -> decltype(data){ return 0; }; };
294   }
295 };
296 
297 } // namespace ns2
298 
299 } // namespace PR32831
300 
301 namespace PR45881 {
302 struct A {
303     void f();
304 };
305 int id(A*);
f()306 void A::f() {
307     auto z = [*this](auto z2, decltype(z2(this)) z3){};
308     z(id,3);
309 }
310 } // namespace PR45881
311 
312 
313 namespace GH50866 {
314 struct S;
315 
316 void f(S *) = delete; // expected-note {{would lose const qualifier}}
317 void f(const S *) = delete; // expected-note {{candidate function has been explicitly deleted}}
318 
319 struct S {
gGH50866::S320   void g() const {
321     [*this]() mutable { f(this); }(); // expected-error {{call to deleted function}}
322   }
323 };
324 
g()325 void g() {
326   S s{};
327   s.g();
328 }
329 }
330