330 lines · cpp
1// RUN: %clang_cc1 -std=c++1z -verify -fblocks -emit-llvm-only %s2// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s -DDELAYED_TEMPLATE_PARSING3// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fms-extensions %s -DMS_EXTENSIONS4// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing -fms-extensions %s -DMS_EXTENSIONS -DDELAYED_TEMPLATE_PARSING5 6// RUN: %clang_cc1 -std=c++1z -verify -fblocks -emit-llvm-only %s -fexperimental-new-constant-interpreter7// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s -DDELAYED_TEMPLATE_PARSING -fexperimental-new-constant-interpreter8// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fms-extensions %s -DMS_EXTENSIONS -fexperimental-new-constant-interpreter9// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing -fms-extensions %s -DMS_EXTENSIONS -DDELAYED_TEMPLATE_PARSING -fexperimental-new-constant-interpreter10 11template <class, class>12constexpr bool is_same = false;13template <class T>14constexpr bool is_same<T, T> = true;15 16namespace test_star_this {17namespace ns1 {18class A {19 int x = 345;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 ns132 33namespace ns2 {34class B {35 B(const B &) = delete; //expected-note{{deleted here}}36 int *x = (int *)456;37 void foo() {38 (void)[this] { return x; };39 (void)[*this] { return x; }; //expected-error{{call to deleted}}40 }41};42} // namespace ns243 44namespace ns3 {45class B {46 B(const B &) = delete; //expected-note2{{deleted here}}47 48 int *x = (int *)456;49 50public:51 template <class T = int>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;59B *c = (b.foo(), nullptr); //expected-note{{in instantiation}}60} // namespace ns361 62namespace ns4 {63template <class U>64class B {65 B(const B &) = delete; //expected-note{{deleted here}}66 double d = 3.14;67 68public:69 template <class T = int>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};79void main() {80 B<int *> b;81 b.foo(); //expected-note{{in instantiation}}82} // end main83} // namespace ns484 85namespace ns5 {86 87struct X {88 double d = 3.14;89 X(const volatile X &);90 void foo() {91 }92 93 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 }161 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 ns5187namespace ns6 {188struct X {189 double d;190 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 208int main() {209 auto L = X{}.foo();210 auto M = L();211 M(3.14);212}213} // namespace ns6214namespace ns7 {215 216struct X {217 double d;218 X();219 X(const X &);220 X(X &) = delete;221 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};226int main() {227 X x;228 x.foo();229}230} // namespace ns7231 232} // namespace test_star_this233 234namespace PR32831 {235// https://bugs.llvm.org/show_bug.cgi?id=32831236namespace ns1 {237template <typename Func>238void fun_template(Func func) {239 (void)[&]() {240 func(0);241 };242}243 244class A {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 ns1260 261namespace ns2 {262 263struct B {264 int data = 0;265 template <class F>266 void mem2(F f) {267 (void)[&](auto f) {268 (void)[&] { f(this->data); };269 }270 (f);271 }272};273 274class A {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;289 auto m2() {290 return [this] { return [] () -> decltype(data){ return 0; }; };291 }292 auto m3() {293 return [] { return [] () -> decltype(data){ return 0; }; };294 }295};296 297} // namespace ns2298 299} // namespace PR32831300 301namespace PR45881 {302struct A {303 void f();304};305int id(A*);306void A::f() {307 auto z = [*this](auto z2, decltype(z2(this)) z3){};308 z(id,3);309}310} // namespace PR45881311 312 313namespace GH50866 {314struct S;315 316void f(S *) = delete; // expected-note {{would lose const qualifier}}317void f(const S *) = delete; // expected-note {{candidate function has been explicitly deleted}}318 319struct S {320 void g() const {321 [*this]() mutable { f(this); }(); // expected-error {{call to deleted function}}322 }323};324 325void g() {326 S s{};327 s.g();328}329}330