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 
6 template <class, class>
7 constexpr bool is_same = false;
8 template <class T>
9 constexpr bool is_same<T, T> = true;
10 
11 namespace test_star_this {
12 namespace ns1 {
13 class A {
14   int x = 345;
foo()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 
28 namespace ns2 {
29 class B {
30   B(const B &) = delete; //expected-note{{deleted here}}
31   int *x = (int *)456;
foo()32   void foo() {
33     (void)[this] { return x; };
34     (void)[*this] { return x; }; //expected-error{{call to deleted}}
35   }
36 };
37 } // namespace ns2
38 
39 namespace ns3 {
40 class B {
41   B(const B &) = delete; //expected-note2{{deleted here}}
42 
43   int *x = (int *)456;
44 
45 public:
46   template <class T = int>
foo()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;
54 B *c = (b.foo(), nullptr); //expected-note{{in instantiation}}
55 } // namespace ns3
56 
57 namespace ns4 {
58 template <class U>
59 class B {
60   B(const B &) = delete; //expected-note{{deleted here}}
61   double d = 3.14;
62 
63 public:
64   template <class T = int>
foo()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 };
main()74 void main() {
75   B<int *> b;
76   b.foo(); //expected-note{{in instantiation}}
77 } // end main
78 } // namespace ns4
79 
80 namespace ns5 {
81 
82 struct X {
83   double d = 3.14;
84   X(const volatile X &);
footest_star_this::ns5::X85   void foo() {
86   }
87 
footest_star_this::ns5::X88   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   }
footest_star_this::ns5::X160   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
186 namespace ns6 {
187 struct X {
188   double d;
footest_star_this::ns6::X189   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 
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