1 // RUN: %clang_cc1 -std=c++0x -Wno-unused-value -fsyntax-only -verify -fblocks %s 2 3 namespace std { class type_info; }; 4 5 namespace ExplicitCapture { 6 class C { 7 int Member; 8 9 static void Overload(int); 10 void Overload(); 11 virtual C& Overload(float); 12 13 void ImplicitThisCapture() { 14 [](){(void)Member;}; // expected-error {{'this' cannot be implicitly captured in this context}} 15 [&](){(void)Member;}; 16 17 [this](){(void)Member;}; 18 [this]{[this]{};}; 19 []{[this]{};};// expected-error {{'this' cannot be implicitly captured in this context}} 20 []{Overload(3);}; 21 []{Overload();}; // expected-error {{'this' cannot be implicitly captured in this context}} 22 []{(void)typeid(Overload());}; 23 []{(void)typeid(Overload(.5f));};// expected-error {{'this' cannot be implicitly captured in this context}} 24 } 25 }; 26 27 void f() { 28 [this] () {}; // expected-error {{'this' cannot be captured in this context}} 29 } 30 } 31 32 namespace ReturnDeduction { 33 void test() { 34 [](){ return 1; }; 35 [](){ return 1; }; 36 [](){ return ({return 1; 1;}); }; 37 [](){ return ({return 'c'; 1;}); }; // expected-error {{must match previous return type}} 38 []()->int{ return 'c'; return 1; }; 39 [](){ return 'c'; return 1; }; // expected-error {{must match previous return type}} 40 []() { return; return (void)0; }; 41 [](){ return 1; return 1; }; 42 } 43 } 44 45 namespace ImplicitCapture { 46 void test() { 47 int a = 0; // expected-note 5 {{declared}} 48 []() { return a; }; // expected-error {{variable 'a' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{begins here}} 49 [&]() { return a; }; 50 [=]() { return a; }; 51 [=]() { int* b = &a; }; // expected-error {{cannot initialize a variable of type 'int *' with an rvalue of type 'const int *'}} 52 [=]() { return [&]() { return a; }; }; 53 []() { return [&]() { return a; }; }; // expected-error {{variable 'a' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{lambda expression begins here}} 54 []() { return ^{ return a; }; };// expected-error {{variable 'a' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{lambda expression begins here}} 55 []() { return [&a] { return a; }; }; // expected-error 2 {{variable 'a' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note 2 {{lambda expression begins here}} 56 [=]() { return [&a] { return a; }; }; // 57 58 const int b = 2; 59 []() { return b; }; 60 61 union { // expected-note {{declared}} 62 int c; 63 float d; 64 }; 65 d = 3; 66 [=]() { return c; }; // expected-error {{unnamed variable cannot be implicitly captured in a lambda expression}} 67 68 __block int e; // expected-note 3 {{declared}} 69 [&]() { return e; }; // expected-error {{__block variable 'e' cannot be captured in a lambda expression}} 70 [&e]() { return e; }; // expected-error 2 {{__block variable 'e' cannot be captured in a lambda expression}} 71 72 int f[10]; // expected-note {{declared}} 73 [&]() { return f[2]; }; 74 (void) ^{ return []() { return f[2]; }; }; // expected-error {{variable 'f' cannot be implicitly captured in a lambda with no capture-default specified}} \ 75 // expected-note{{lambda expression begins here}} 76 77 struct G { G(); G(G&); int a; }; // expected-note 6 {{not viable}} 78 G g; 79 [=]() { const G* gg = &g; return gg->a; }; 80 [=]() { return [=]{ const G* gg = &g; return gg->a; }(); }; // expected-error {{no matching constructor for initialization of 'G'}} 81 (void)^{ return [=]{ const G* gg = &g; return gg->a; }(); }; // expected-error 2 {{no matching constructor for initialization of 'const G'}} 82 83 const int h = a; // expected-note {{declared}} 84 []() { return h; }; // expected-error {{variable 'h' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{lambda expression begins here}} 85 86 // References can appear in constant expressions if they are initialized by 87 // reference constant expressions. 88 int i; 89 int &ref_i = i; // expected-note {{declared}} 90 [] { return ref_i; }; // expected-error {{variable 'ref_i' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{lambda expression begins here}} 91 92 static int j; 93 int &ref_j = j; 94 [] { return ref_j; }; // ok 95 } 96 } 97 98 namespace PR12031 { 99 struct X { 100 template<typename T> 101 X(const T&); 102 ~X(); 103 }; 104 105 void f(int i, X x); 106 void g() { 107 const int v = 10; 108 f(v, [](){}); 109 } 110 } 111 112 namespace NullPtr { 113 int &f(int *p); 114 char &f(...); 115 void g() { 116 int n = 0; 117 [=] { 118 char &k = f(n); // not a null pointer constant 119 } (); 120 121 const int m = 0; 122 [=] { 123 int &k = f(m); // expected-warning{{expression which evaluates to zero treated as a null pointer constant of type 'int *'}} 124 } (); 125 126 [=] () -> bool { 127 int &k = f(m); // expected-warning{{expression which evaluates to zero treated as a null pointer constant of type 'int *'}} 128 return &m == 0; 129 } (); 130 131 [m] { 132 int &k = f(m); // expected-warning{{expression which evaluates to zero treated as a null pointer constant of type 'int *'}} 133 } (); 134 } 135 } 136 137 void PR12248() 138 { 139 unsigned int result = 0; 140 auto l = [&]() { ++result; }; 141 } 142 143 namespace ModifyingCapture { 144 void test() { 145 int n = 0; 146 [=] { 147 n = 1; // expected-error {{cannot assign to a variable captured by copy in a non-mutable lambda}} 148 }; 149 } 150 } 151 152 namespace VariadicPackExpansion { 153 template<typename T, typename U> using Fst = T; 154 template<typename...Ts> bool g(Fst<bool, Ts> ...bools); 155 template<typename...Ts> bool f(Ts &&...ts) { 156 return g<Ts...>([&ts] { 157 if (!ts) 158 return false; 159 --ts; 160 return true; 161 } () ...); 162 } 163 void h() { 164 int a = 5, b = 2, c = 3; 165 while (f(a, b, c)) { 166 } 167 } 168 169 struct sink { 170 template<typename...Ts> sink(Ts &&...) {} 171 }; 172 173 template<typename...Ts> void local_class() { 174 sink { 175 [] (Ts t) { 176 struct S : Ts { 177 void f(Ts t) { 178 Ts &that = *this; 179 that = t; 180 } 181 Ts g() { return *this; }; 182 }; 183 S s; 184 s.f(t); 185 return s; 186 } (Ts()).g() ... 187 }; 188 }; 189 struct X {}; struct Y {}; 190 template void local_class<X, Y>(); 191 192 template<typename...Ts> void nested(Ts ...ts) { 193 f( 194 // Each expansion of this lambda implicitly captures all of 'ts', because 195 // the inner lambda also expands 'ts'. 196 [&] { 197 return ts + [&] { return f(ts...); } (); 198 } () ... 199 ); 200 } 201 template void nested(int, int, int); 202 203 template<typename...Ts> void nested2(Ts ...ts) { // expected-note 2{{here}} 204 // Capture all 'ts', use only one. 205 f([&ts...] { return ts; } ()...); 206 // Capture each 'ts', use it. 207 f([&ts] { return ts; } ()...); 208 // Capture all 'ts', use all of them. 209 f([&ts...] { return (int)f(ts...); } ()); 210 // Capture each 'ts', use all of them. Ill-formed. In more detail: 211 // 212 // We instantiate two lambdas here; the first captures ts$0, the second 213 // captures ts$1. Both of them reference both ts parameters, so both are 214 // ill-formed because ts can't be implicitly captured. 215 // 216 // FIXME: This diagnostic does not explain what's happening. We should 217 // specify which 'ts' we're referring to in its diagnostic name. We should 218 // also say which slice of the pack expansion is being performed in the 219 // instantiation backtrace. 220 f([&ts] { return (int)f(ts...); } ()...); // \ 221 // expected-error 2{{'ts' cannot be implicitly captured}} \ 222 // expected-note 2{{lambda expression begins here}} 223 } 224 template void nested2(int); // ok 225 template void nested2(int, int); // expected-note {{in instantiation of}} 226 } 227 228 namespace PR13860 { 229 void foo() { 230 auto x = PR13860UndeclaredIdentifier(); // expected-error {{use of undeclared identifier 'PR13860UndeclaredIdentifier'}} 231 auto y = [x]() { }; 232 static_assert(sizeof(y), ""); 233 } 234 } 235 236 namespace PR13854 { 237 auto l = [](void){}; 238 } 239 240 namespace PR14518 { 241 auto f = [](void) { return __func__; }; // no-warning 242 } 243