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