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; 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; 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> 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> 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 }; 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&); 79 void foo() { 80 81 } 82 83 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 } 156 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; 186 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 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; 218 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 }; 224 int main() { 225 X x; 226 x.foo(); 227 } 228 } // end ns7 229 230 } //end ns test_star_this 231 232