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> constexpr bool is_same = false;
7 template<class T> constexpr bool is_same<T, T> = true;
8
9 namespace test_star_this {
10 namespace ns1 {
11 class A {
12 int x = 345;
foo()13 auto foo() {
14 (void) [*this, this] { }; //expected-error{{'this' can appear only once}}
15 (void) [this] { ++x; };
16 (void) [*this] { ++x; }; //expected-error{{read-only variable}}
17 (void) [*this] () mutable { ++x; };
18 (void) [=] { return x; };
19 (void) [&, this] { return x; };
20 (void) [=, *this] { return x; };
21 (void) [&, *this] { return x; };
22 }
23 };
24 } // end ns1
25
26 namespace ns2 {
27 class B {
28 B(const B&) = delete; //expected-note{{deleted here}}
29 int *x = (int *) 456;
foo()30 void foo() {
31 (void)[this] { return x; };
32 (void)[*this] { return x; }; //expected-error{{call to deleted}}
33 }
34 };
35 } // end ns2
36 namespace ns3 {
37 class B {
38 B(const B&) = delete; //expected-note2{{deleted here}}
39
40 int *x = (int *) 456;
41 public:
42 template<class T = int>
foo()43 void foo() {
44 (void)[this] { return x; };
45 (void)[*this] { return x; }; //expected-error2{{call to deleted}}
46 }
47
48 B() = default;
49 } b;
50 B *c = (b.foo(), nullptr); //expected-note{{in instantiation}}
51 } // end ns3
52
53 namespace ns4 {
54 template<class U>
55 class B {
56 B(const B&) = delete; //expected-note{{deleted here}}
57 double d = 3.14;
58 public:
59 template<class T = int>
foo()60 auto foo() {
61 const auto &L = [*this] (auto a) mutable { //expected-error{{call to deleted}}
62 d += a;
63 return [this] (auto b) { return d +=b; };
64 };
65 }
66
67 B() = default;
68 };
main()69 void main() {
70 B<int*> b;
71 b.foo(); //expected-note{{in instantiation}}
72 } // end main
73 } // end ns4
74 namespace ns5 {
75
76 struct X {
77 double d = 3.14;
78 X(const volatile X&);
footest_star_this::ns5::X79 void foo() {
80
81 }
82
footest_star_this::ns5::X83 void foo() const { //expected-note{{const}}
84
85 auto L = [*this] () mutable {
86 static_assert(is_same<decltype(this), X*>);
87 ++d;
88 auto M = [this] {
89 static_assert(is_same<decltype(this), X*>);
90 ++d;
91 auto N = [] {
92 static_assert(is_same<decltype(this), X*>);
93 };
94 };
95 };
96
97 auto L1 = [*this] {
98 static_assert(is_same<decltype(this), const X*>);
99 auto M = [this] () mutable {
100 static_assert(is_same<decltype(this), const X*>);
101 auto N = [] {
102 static_assert(is_same<decltype(this), const X*>);
103 };
104 };
105 auto M2 = [*this] () mutable {
106 static_assert(is_same<decltype(this), X*>);
107 auto N = [] {
108 static_assert(is_same<decltype(this), X*>);
109 };
110 };
111 };
112
113 auto GL1 = [*this] (auto a) {
114 static_assert(is_same<decltype(this), const X*>);
115 auto M = [this] (auto b) mutable {
116 static_assert(is_same<decltype(this), const X*>);
117 auto N = [] (auto c) {
118 static_assert(is_same<decltype(this), const X*>);
119 };
120 return N;
121 };
122
123 auto M2 = [*this] (auto a) mutable {
124 static_assert(is_same<decltype(this), X*>);
125 auto N = [] (auto b) {
126 static_assert(is_same<decltype(this), X*>);
127 };
128 return N;
129 };
130 return [=](auto a) mutable { M(a)(a); M2(a)(a); };
131 };
132
133 GL1("abc")("abc");
134
135
136 auto L2 = [this] () mutable {
137 static_assert(is_same<decltype(this), const X*>);
138 ++d; //expected-error{{cannot assign}}
139 };
140 auto GL = [*this] (auto a) mutable {
141 static_assert(is_same<decltype(this), X*>);
142 ++d;
143 auto M = [this] (auto b) {
144 static_assert(is_same<decltype(this), X*>);
145 ++d;
146 auto N = [] (auto c) {
147 static_assert(is_same<decltype(this), X*>);
148 };
149 N(3.14);
150 };
151 M("abc");
152 };
153 GL(3.14);
154
155 }
footest_star_this::ns5::X156 void foo() volatile const {
157 auto L = [this] () {
158 static_assert(is_same<decltype(this), const volatile X*>);
159 auto M = [*this] () mutable {
160 static_assert(is_same<decltype(this), X*>);
161 auto N = [this] {
162 static_assert(is_same<decltype(this), X*>);
163 auto M = [] {
164 static_assert(is_same<decltype(this), X*>);
165 };
166 };
167 auto N2 = [*this] {
168 static_assert(is_same<decltype(this), const X*>);
169 };
170 };
171 auto M2 = [*this] () {
172 static_assert(is_same<decltype(this), const X*>);
173 auto N = [this] {
174 static_assert(is_same<decltype(this), const X*>);
175 };
176 };
177 };
178 }
179
180 };
181
182 } //end ns5
183 namespace ns6 {
184 struct X {
185 double d;
footest_star_this::ns6::X186 auto foo() const {
187 auto L = [*this] () mutable {
188 auto M = [=] (auto a) {
189 auto N = [this] {
190 ++d;
191 static_assert(is_same<decltype(this), X*>);
192 auto O = [*this] {
193 static_assert(is_same<decltype(this), const X*>);
194 };
195 };
196 N();
197 static_assert(is_same<decltype(this), X*>);
198 };
199 return M;
200 };
201 return L;
202 }
203 };
204
main()205 int main() {
206 auto L = X{}.foo();
207 auto M = L();
208 M(3.14);
209 }
210 } // end ns6
211 namespace ns7 {
212
213 struct X {
214 double d;
215 X();
216 X(const X&);
217 X(X&) = delete;
footest_star_this::ns7::X218 auto foo() const {
219 //OK - the object used to initialize our capture is a const object and so prefers the non-deleted ctor.
220 const auto &&L = [*this] { };
221 }
222
223 };
main()224 int main() {
225 X x;
226 x.foo();
227 }
228 } // end ns7
229
230 } //end ns test_star_this
231
232