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