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