408 lines · cpp
1// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks %s -fcxx-exceptions2// RUN: %clang_cc1 -std=c++20 -verify -fsyntax-only -fblocks %s -fcxx-exceptions3// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s -fcxx-exceptions4// RUN: %clang_cc1 -std=c++14 -verify -fsyntax-only -fblocks %s -DCPP14_AND_EARLIER -fcxx-exceptions5 6// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks %s -fcxx-exceptions -fexperimental-new-constant-interpreter7// RUN: %clang_cc1 -std=c++20 -verify -fsyntax-only -fblocks %s -fcxx-exceptions -fexperimental-new-constant-interpreter8// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s -fcxx-exceptions -fexperimental-new-constant-interpreter9// RUN: %clang_cc1 -std=c++14 -verify -fsyntax-only -fblocks %s -DCPP14_AND_EARLIER -fcxx-exceptions -fexperimental-new-constant-interpreter10 11namespace test_lambda_is_literal {12#ifdef CPP14_AND_EARLIER13//expected-error@+4{{not a literal type}}14//expected-note@+2{{lambda closure types are non-literal types before C++17}}15#endif16auto L = [] { };17constexpr int foo(decltype(L) l) { return 0; }18 19}20 21#ifndef CPP14_AND_EARLIER22namespace test_constexpr_checking {23 24namespace ns1 {25 struct NonLit { ~NonLit(); }; //expected-note{{not literal}}26 auto L = [](NonLit NL) constexpr { }; //expected-error{{not a literal type}}27} // end ns128 29namespace ns2 {30 auto L = [](int I) constexpr { if (I == 5) asm("non-constexpr"); };31#if __cpp_constexpr < 201907L32 //expected-warning@-2{{use of this statement in a constexpr function is a C++20 extension}}33#endif34} // end ns135 36// This is not constexpr until C++20, as the requirements on constexpr37// functions don't permit try-catch blocks.38#if __cplusplus <= 201703L39// expected-error@#try-catch {{constant expression}}40// expected-note@#try-catch {{non-constexpr function 'operator()'}}41// expected-note@#try-catch {{declared here}}42#endif43constexpr int try_catch = [] { // #try-catch44 try { return 0; } catch (...) { return 1; }45}();46 47// These lambdas have constexpr operator() even though they can never produce a48// constant expression.49auto never_constant_1 = [] { // expected-note {{here}}50 volatile int n = 0;51 return n;52};53auto never_constant_2 = [] () -> int { // expected-note {{here}}54};55struct test_never_constant {56 #if __cplusplus >= 201703L57 // expected-error@+3 {{non-constexpr declaration of 'operator()' follows constexpr declaration}}58 // expected-error@+3 {{non-constexpr declaration of 'operator()' follows constexpr declaration}}59 #endif60 friend auto decltype(never_constant_1)::operator()() const;61 friend int decltype(never_constant_2)::operator()() const;62};63 64} // end ns test_constexpr_checking65 66namespace test_constexpr_call {67 68namespace ns1 {69 auto L = [](int I) { return I; };70 static_assert(L(3) == 3);71} // end ns172namespace ns2 {73 auto L = [](auto a) { return a; };74 static_assert(L(3) == 3);75 static_assert(L(3.14) == 3.14);76}77namespace ns3 {78 auto L = [](auto a) { asm("non-constexpr"); return a; };79 constexpr int I = //expected-error{{must be initialized by a constant expression}}80 L(3);81#if __cpp_constexpr < 201907L82//expected-note@-2{{non-constexpr function}}83//expected-note@-5{{declared here}}84#else85//expected-note@-7{{subexpression not valid in a constant expression}}86//expected-note@-6{{in call to}}87#endif88} 89 90} // end ns test_constexpr_call91 92namespace test_captureless_lambda {93void f() {94 const char c = 'c';95 auto L = [] { return c; };96 constexpr char C = L();97}98 99void f(char c) { //expected-note{{declared here}}100 auto L = [] { return c; }; //expected-error{{cannot be implicitly captured}} expected-note{{lambda expression begins here}} expected-note 2 {{capture 'c' by}} expected-note 2 {{default capture by}}101 int I = L();102}103 104}105 106namespace test_conversion_function_for_non_capturing_lambdas {107 108namespace ns1 {109auto L = [](int i) { return i; };110constexpr int (*fpi)(int) = L;111static_assert(fpi(3) == 3);112auto GL = [](auto a) { return a; };113 114constexpr char (*fp2)(char) = GL;115constexpr double (*fp3)(double) = GL;116constexpr const char* (*fp4)(const char*) = GL;117static_assert(fp2('3') == '3');118static_assert(fp3(3.14) == 3.14);119constexpr const char *Str = "abc";120static_assert(fp4(Str) == Str);121 122auto NCL = [](int i) { static int j; return j; }; //expected-note{{declared here}}123constexpr int (*fp5)(int) = NCL;124constexpr int I = //expected-error{{must be initialized by a constant expression}}125 fp5(5); //expected-note{{non-constexpr function}} 126 127namespace test_dont_always_instantiate_constexpr_templates {128 129auto explicit_return_type = [](auto x) -> int { return x.get(); };130decltype(explicit_return_type(0)) c; // OK131 132auto deduced_return_type = [](auto x) { return x.get(); }; //expected-error{{not a structure or union}}133decltype(deduced_return_type(0)) d; //expected-note{{requested here}}134 135 136 137} // end ns test_dont_always_instantiate_constexpr_templates138} // end ns1139 140} // end ns test_conversion_function_for_non_capturing_lambdas141 142namespace test_lambda_is_cce {143namespace ns1_simple_lambda {144 145namespace ns0 {146constexpr int I = [](auto a) { return a; }(10);147 148static_assert(I == 10); 149static_assert(10 == [](auto a) { return a; }(10));150static_assert(3.14 == [](auto a) { return a; }(3.14));151 152} //end ns0153 154namespace ns1 {155constexpr auto f(int i) {156 double d = 3.14;157 auto L = [=](auto a) { 158 int Isz = sizeof(i);159 return sizeof(i) + sizeof(a) + sizeof(d); 160 };161 int I = L("abc") + L(nullptr);162 return L;163}164constexpr auto L = f(3);165constexpr auto M = L("abc") + L(nullptr);166 167static_assert(M == sizeof(int) * 2 + sizeof(double) * 2 + sizeof(nullptr) + sizeof(const char*));168 169} // end ns1170 171namespace ns2 {172constexpr auto f(int i) {173 auto L = [](auto a) { return a + a; };174 return L;175}176constexpr auto L = f(3);177constexpr int I = L(6);178static_assert(I == 12);179} // end ns2180 181namespace contained_lambdas_call_operator_is_not_constexpr {182constexpr auto f(int i) {183 double d = 3.14;184 auto L = [=](auto a) {185 int Isz = sizeof(i);186 asm("hello");187 return sizeof(i) + sizeof(a) + sizeof(d); 188 };189 return L;190}191 192constexpr auto L = f(3);193 194constexpr auto M = // expected-error{{must be initialized by}} 195 L("abc");196#if __cpp_constexpr < 201907L197//expected-note@-2{{non-constexpr function}}198//expected-note@-14{{declared here}}199#else200//expected-note@-14{{subexpression not valid in a constant expression}}201//expected-note@-6{{in call to}}202#endif203} // end ns contained_lambdas_call_operator_is_not_constexpr204 205 206 207} // end ns1_simple_lambda208 209namespace test_captures_1 {210namespace ns1 {211constexpr auto f(int i) {212 struct S { int x; } s = { i * 2 };213 auto L = [=](auto a) { 214 return i + s.x + a;215 };216 return L;217}218constexpr auto M = f(3); 219 220static_assert(M(10) == 19);221 222} // end test_captures_1::ns1223 224namespace ns2 {225 226constexpr auto foo(int n) {227 auto L = [i = n] (auto N) mutable {228 if (!N(i)) throw "error";229 return [&i] {230 return ++i;231 };232 };233 auto M = L([n](int p) { return p == n; });234 M(); M();235 L([n](int p) { return p == n + 2; });236 237 return L;238}239 240constexpr auto L = foo(3);241 242} // end test_captures_1::ns2243namespace ns3 {244 245constexpr auto foo(int n) {246 auto L = [i = n] (auto N) mutable {247 if (!N(i)) throw "error";248 return [&i] {249 return [i]() mutable {250 return ++i;251 };252 };253 };254 auto M = L([n](int p) { return p == n; });255 M()(); M()();256 L([n](int p) { return p == n; });257 258 return L;259}260 261constexpr auto L = foo(3);262} // end test_captures_1::ns3263 264namespace ns2_capture_this_byval {265struct S {266 int s;267 constexpr S(int s) : s{s} { }268 constexpr auto f(S o) {269 return [*this,o] (auto a) { return s + o.s + a.s; };270 }271};272 273constexpr auto L = S{5}.f(S{10});274static_assert(L(S{100}) == 115);275} // end test_captures_1::ns2_capture_this_byval276 277namespace ns2_capture_this_byref {278 279struct S {280 int s;281 constexpr S(int s) : s{s} { }282 constexpr auto f() const {283 return [this] { return s; };284 }285};286 287constexpr S SObj{5};288constexpr auto L = SObj.f();289constexpr int I = L();290static_assert(I == 5);291 292} // end ns2_capture_this_byref293 294} // end test_captures_1295 296namespace test_capture_array {297namespace ns1 {298constexpr auto f(int I) {299 int arr[] = { I, I *2, I * 3 };300 auto L1 = [&] (auto a) { return arr[a]; };301 int r = L1(2);302 struct X { int x, y; };303 return [=](auto a) { return X{arr[a],r}; };304}305constexpr auto L = f(3);306static_assert(L(0).x == 3);307static_assert(L(0).y == 9);308static_assert(L(1).x == 6);309static_assert(L(1).y == 9);310} // end ns1311 312} // end test_capture_array313namespace ns1_test_lvalue_type {314 void f() {315 volatile int n;316 constexpr bool B = [&]{ return &n; }() == &n; // should be accepted317 }318} // end ns1_unimplemented 319 320} // end ns test_lambda_is_cce321 322namespace PR36054 {323constexpr int fn() {324 int Capture = 42;325 return [=]() constexpr { return Capture; }();326}327 328static_assert(fn() == 42, "");329 330template <class T>331constexpr int tfn() {332 int Capture = 42;333 return [=]() constexpr { return Capture; }();334}335 336static_assert(tfn<int>() == 42, "");337 338constexpr int gfn() {339 int Capture = 42;340 return [=](auto P) constexpr { return Capture + P; }(58);341}342 343static_assert(gfn() == 100, "");344 345constexpr bool OtherCaptures() {346 int Capture = 42;347 constexpr auto Outer = [](auto P) constexpr { return 42 + P; };348 auto Inner = [&](auto O) constexpr { return O(58) + Capture; };349 return Inner(Outer) == 142;350}351 352static_assert(OtherCaptures(), "");353} // namespace PR36054354 355#endif // ndef CPP14_AND_EARLIER356 357 358#if __cpp_constexpr >= 201907L359namespace GH114234 {360template <auto Arg>361auto g() { return Arg; }362 363template <typename>364auto f() {365 []<typename>() {366 g<[] { return 123; }()>();367 }.template operator()<int>();368}369 370void test() { f<int>(); }371}372 373namespace GH97958 {374static_assert(375 []<int I=0>() -> decltype([]{ return true; })376 { return {}; }()());377}378 379#endif380 381#ifndef CPP14_AND_EARLIER382namespace GH145956 {383 constexpr int f() {384 struct Pair { int first; int second; };385 Pair p = {1, 2};386 auto const& [key, value] = p;387 return [&] { return key; }();388#if __cpp_constexpr < 202002L389 // expected-warning@-2 {{captured structured bindings are a C++20 extension}}390 // expected-note@-4 {{'key' declared here}}391#endif392 }393 static_assert(f() == 1);394 constexpr auto retlambda() {395 struct Pair { int first; int second; };396 Pair p = {1, 2};397 auto const& [key, value] = p;398 return [=] { return key; };399#if __cpp_constexpr < 202002L400 // expected-warning@-2 {{captured structured bindings are a C++20 extension}}401 // expected-note@-4 {{'key' declared here}}402#endif403 }404 constexpr auto lambda = retlambda();405 static_assert(lambda() == 1);406}407#endif408