1*a07aba5dSTimm Baeder // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify=expected,both -std=c++20 %s 2*a07aba5dSTimm Baeder // RUN: %clang_cc1 -verify=ref,both -std=c++20 %s 3*a07aba5dSTimm Baeder 4*a07aba5dSTimm Baeder constexpr int a = 12; 5*a07aba5dSTimm Baeder constexpr int f = [c = a]() { return c; }(); 6*a07aba5dSTimm Baeder static_assert(f == a); 7*a07aba5dSTimm Baeder 8*a07aba5dSTimm Baeder 9*a07aba5dSTimm Baeder constexpr int inc() { 10*a07aba5dSTimm Baeder int a = 10; 11*a07aba5dSTimm Baeder auto f = [&a]() { 12*a07aba5dSTimm Baeder ++a; 13*a07aba5dSTimm Baeder }; 14*a07aba5dSTimm Baeder 15*a07aba5dSTimm Baeder f();f(); 16*a07aba5dSTimm Baeder 17*a07aba5dSTimm Baeder return a; 18*a07aba5dSTimm Baeder } 19*a07aba5dSTimm Baeder static_assert(inc() == 12); 20*a07aba5dSTimm Baeder 21*a07aba5dSTimm Baeder constexpr int add(int a, int b) { 22*a07aba5dSTimm Baeder auto doIt = [a, b](int c) { 23*a07aba5dSTimm Baeder return a + b + c; 24*a07aba5dSTimm Baeder }; 25*a07aba5dSTimm Baeder 26*a07aba5dSTimm Baeder return doIt(2); 27*a07aba5dSTimm Baeder } 28*a07aba5dSTimm Baeder static_assert(add(4, 5) == 11); 29*a07aba5dSTimm Baeder 30*a07aba5dSTimm Baeder 31*a07aba5dSTimm Baeder constexpr int add2(int a, int b) { 32*a07aba5dSTimm Baeder auto doIt = [a, b](int c) { 33*a07aba5dSTimm Baeder auto bar = [a]() { return a; }; 34*a07aba5dSTimm Baeder auto bar2 = [b]() { return b; }; 35*a07aba5dSTimm Baeder 36*a07aba5dSTimm Baeder return bar() + bar2() + c; 37*a07aba5dSTimm Baeder }; 38*a07aba5dSTimm Baeder 39*a07aba5dSTimm Baeder return doIt(2); 40*a07aba5dSTimm Baeder } 41*a07aba5dSTimm Baeder static_assert(add2(4, 5) == 11); 42*a07aba5dSTimm Baeder 43*a07aba5dSTimm Baeder 44*a07aba5dSTimm Baeder constexpr int div(int a, int b) { 45*a07aba5dSTimm Baeder auto f = [=]() { 46*a07aba5dSTimm Baeder return a / b; // both-note {{division by zero}} 47*a07aba5dSTimm Baeder }; 48*a07aba5dSTimm Baeder 49*a07aba5dSTimm Baeder return f(); // both-note {{in call to 'f.operator()()'}} 50*a07aba5dSTimm Baeder } 51*a07aba5dSTimm Baeder static_assert(div(8, 2) == 4); 52*a07aba5dSTimm Baeder static_assert(div(8, 0) == 4); // both-error {{not an integral constant expression}} \ 53*a07aba5dSTimm Baeder // both-note {{in call to 'div(8, 0)'}} 54*a07aba5dSTimm Baeder 55*a07aba5dSTimm Baeder 56*a07aba5dSTimm Baeder struct F { 57*a07aba5dSTimm Baeder float f; 58*a07aba5dSTimm Baeder }; 59*a07aba5dSTimm Baeder 60*a07aba5dSTimm Baeder constexpr float captureStruct() { 61*a07aba5dSTimm Baeder F someF = {1.0}; 62*a07aba5dSTimm Baeder 63*a07aba5dSTimm Baeder auto p = [someF]() { 64*a07aba5dSTimm Baeder return someF.f; 65*a07aba5dSTimm Baeder }; 66*a07aba5dSTimm Baeder 67*a07aba5dSTimm Baeder return p(); 68*a07aba5dSTimm Baeder } 69*a07aba5dSTimm Baeder 70*a07aba5dSTimm Baeder static_assert(captureStruct() == 1.0); 71*a07aba5dSTimm Baeder 72*a07aba5dSTimm Baeder 73*a07aba5dSTimm Baeder int constexpr FunCase() { 74*a07aba5dSTimm Baeder return [x = 10] { 75*a07aba5dSTimm Baeder decltype(x) y; // type int b/c not odr use 76*a07aba5dSTimm Baeder // refers to original init-capture 77*a07aba5dSTimm Baeder auto &z = x; // type const int & b/c odr use 78*a07aba5dSTimm Baeder // refers to lambdas copy of x 79*a07aba5dSTimm Baeder y = 10; // Ok 80*a07aba5dSTimm Baeder //z = 10; // Ill-formed 81*a07aba5dSTimm Baeder return y; 82*a07aba5dSTimm Baeder }(); 83*a07aba5dSTimm Baeder } 84*a07aba5dSTimm Baeder 85*a07aba5dSTimm Baeder constexpr int WC = FunCase(); 86*a07aba5dSTimm Baeder 87*a07aba5dSTimm Baeder 88*a07aba5dSTimm Baeder namespace LambdaParams { 89*a07aba5dSTimm Baeder template<typename T> 90*a07aba5dSTimm Baeder constexpr void callThis(T t) { 91*a07aba5dSTimm Baeder return t(); 92*a07aba5dSTimm Baeder } 93*a07aba5dSTimm Baeder 94*a07aba5dSTimm Baeder constexpr int foo() { 95*a07aba5dSTimm Baeder int a = 0; 96*a07aba5dSTimm Baeder auto f = [&a]() { ++a; }; 97*a07aba5dSTimm Baeder 98*a07aba5dSTimm Baeder callThis(f); 99*a07aba5dSTimm Baeder 100*a07aba5dSTimm Baeder return a; 101*a07aba5dSTimm Baeder } 102*a07aba5dSTimm Baeder static_assert(foo() == 1); 103*a07aba5dSTimm Baeder } 104*a07aba5dSTimm Baeder 105*a07aba5dSTimm Baeder namespace StaticInvoker { 106*a07aba5dSTimm Baeder constexpr int sv1(int i) { 107*a07aba5dSTimm Baeder auto l = []() { return 12; }; 108*a07aba5dSTimm Baeder int (*fp)() = l; 109*a07aba5dSTimm Baeder return fp(); 110*a07aba5dSTimm Baeder } 111*a07aba5dSTimm Baeder static_assert(sv1(12) == 12); 112*a07aba5dSTimm Baeder 113*a07aba5dSTimm Baeder constexpr int sv2(int i) { 114*a07aba5dSTimm Baeder auto l = [](int m, float f, void *A) { return m; }; 115*a07aba5dSTimm Baeder int (*fp)(int, float, void*) = l; 116*a07aba5dSTimm Baeder return fp(i, 4.0f, nullptr); 117*a07aba5dSTimm Baeder } 118*a07aba5dSTimm Baeder static_assert(sv2(12) == 12); 119*a07aba5dSTimm Baeder 120*a07aba5dSTimm Baeder constexpr int sv3(int i) { 121*a07aba5dSTimm Baeder auto l = [](int m, const int &n) { return m; }; 122*a07aba5dSTimm Baeder int (*fp)(int, const int &) = l; 123*a07aba5dSTimm Baeder return fp(i, 3); 124*a07aba5dSTimm Baeder } 125*a07aba5dSTimm Baeder static_assert(sv3(12) == 12); 126*a07aba5dSTimm Baeder 127*a07aba5dSTimm Baeder constexpr int sv4(int i) { 128*a07aba5dSTimm Baeder auto l = [](int &m) { return m; }; 129*a07aba5dSTimm Baeder int (*fp)(int&) = l; 130*a07aba5dSTimm Baeder return fp(i); 131*a07aba5dSTimm Baeder } 132*a07aba5dSTimm Baeder static_assert(sv4(12) == 12); 133*a07aba5dSTimm Baeder 134*a07aba5dSTimm Baeder constexpr int sv5(int i) { 135*a07aba5dSTimm Baeder struct F { int a; float f; }; 136*a07aba5dSTimm Baeder auto l = [](int m, F f) { return m; }; 137*a07aba5dSTimm Baeder int (*fp)(int, F) = l; 138*a07aba5dSTimm Baeder return fp(i, F{12, 14.0}); 139*a07aba5dSTimm Baeder } 140*a07aba5dSTimm Baeder static_assert(sv5(12) == 12); 141*a07aba5dSTimm Baeder 142*a07aba5dSTimm Baeder constexpr int sv6(int i) { 143*a07aba5dSTimm Baeder struct F { int a; 144*a07aba5dSTimm Baeder constexpr F(int a) : a(a) {} 145*a07aba5dSTimm Baeder }; 146*a07aba5dSTimm Baeder 147*a07aba5dSTimm Baeder auto l = [](int m) { return F(12); }; 148*a07aba5dSTimm Baeder F (*fp)(int) = l; 149*a07aba5dSTimm Baeder F f = fp(i); 150*a07aba5dSTimm Baeder 151*a07aba5dSTimm Baeder return fp(i).a; 152*a07aba5dSTimm Baeder } 153*a07aba5dSTimm Baeder static_assert(sv6(12) == 12); 154*a07aba5dSTimm Baeder 155*a07aba5dSTimm Baeder 156*a07aba5dSTimm Baeder /// A generic lambda. 157*a07aba5dSTimm Baeder auto GL = [](auto a) { return a; }; 158*a07aba5dSTimm Baeder constexpr char (*fp2)(char) = GL; 159*a07aba5dSTimm Baeder static_assert(fp2('3') == '3', ""); 160*a07aba5dSTimm Baeder 161*a07aba5dSTimm Baeder struct GLS { 162*a07aba5dSTimm Baeder int a; 163*a07aba5dSTimm Baeder }; 164*a07aba5dSTimm Baeder auto GL2 = [](auto a) { return GLS{a}; }; 165*a07aba5dSTimm Baeder constexpr GLS (*fp3)(char) = GL2; 166*a07aba5dSTimm Baeder static_assert(fp3('3').a == '3', ""); 167*a07aba5dSTimm Baeder } 168*a07aba5dSTimm Baeder 169*a07aba5dSTimm Baeder namespace LambdasAsParams { 170*a07aba5dSTimm Baeder template<typename F> 171*a07aba5dSTimm Baeder constexpr auto call(F f) { 172*a07aba5dSTimm Baeder return f(); 173*a07aba5dSTimm Baeder } 174*a07aba5dSTimm Baeder static_assert(call([](){ return 1;}) == 1); 175*a07aba5dSTimm Baeder static_assert(call([](){ return 2;}) == 2); 176*a07aba5dSTimm Baeder 177*a07aba5dSTimm Baeder 178*a07aba5dSTimm Baeder constexpr unsigned L = call([](){ return 12;}); 179*a07aba5dSTimm Baeder static_assert(L == 12); 180*a07aba5dSTimm Baeder 181*a07aba5dSTimm Baeder 182*a07aba5dSTimm Baeder constexpr float heh() { 183*a07aba5dSTimm Baeder auto a = []() { 184*a07aba5dSTimm Baeder return 1.0; 185*a07aba5dSTimm Baeder }; 186*a07aba5dSTimm Baeder 187*a07aba5dSTimm Baeder return static_cast<float>(a()); 188*a07aba5dSTimm Baeder } 189*a07aba5dSTimm Baeder static_assert(heh() == 1.0); 190*a07aba5dSTimm Baeder } 191*a07aba5dSTimm Baeder 192*a07aba5dSTimm Baeder namespace ThisCapture { 193*a07aba5dSTimm Baeder class Foo { 194*a07aba5dSTimm Baeder public: 195*a07aba5dSTimm Baeder int b = 32; 196*a07aba5dSTimm Baeder int a; 197*a07aba5dSTimm Baeder 198*a07aba5dSTimm Baeder constexpr Foo() : a([this](){ return b + 1;}()) {} 199*a07aba5dSTimm Baeder 200*a07aba5dSTimm Baeder constexpr int Aplus2() const { 201*a07aba5dSTimm Baeder auto F = [this]() { 202*a07aba5dSTimm Baeder return a + 2; 203*a07aba5dSTimm Baeder }; 204*a07aba5dSTimm Baeder 205*a07aba5dSTimm Baeder return F(); 206*a07aba5dSTimm Baeder } 207*a07aba5dSTimm Baeder }; 208*a07aba5dSTimm Baeder constexpr Foo F; 209*a07aba5dSTimm Baeder static_assert(F.a == 33, ""); 210*a07aba5dSTimm Baeder static_assert(F.Aplus2() == (33 + 2), ""); 211*a07aba5dSTimm Baeder } 212*a07aba5dSTimm Baeder 213*a07aba5dSTimm Baeder namespace GH62611 { 214*a07aba5dSTimm Baeder template <auto A = [](auto x){}> 215*a07aba5dSTimm Baeder struct C { 216*a07aba5dSTimm Baeder static constexpr auto B = A; 217*a07aba5dSTimm Baeder }; 218*a07aba5dSTimm Baeder 219*a07aba5dSTimm Baeder int test() { 220*a07aba5dSTimm Baeder C<>::B(42); 221*a07aba5dSTimm Baeder return 0; 222*a07aba5dSTimm Baeder } 223*a07aba5dSTimm Baeder } 224*a07aba5dSTimm Baeder 225*a07aba5dSTimm Baeder namespace LambdaToAPValue { 226*a07aba5dSTimm Baeder void wrapper() { 227*a07aba5dSTimm Baeder constexpr auto f = []() constexpr { 228*a07aba5dSTimm Baeder return 0; 229*a07aba5dSTimm Baeder }; 230*a07aba5dSTimm Baeder 231*a07aba5dSTimm Baeder constexpr auto g = [f]() constexpr { 232*a07aba5dSTimm Baeder return f(); 233*a07aba5dSTimm Baeder }; 234*a07aba5dSTimm Baeder static_assert(g() == f(), ""); 235*a07aba5dSTimm Baeder } 236*a07aba5dSTimm Baeder } 237*a07aba5dSTimm Baeder 238*a07aba5dSTimm Baeder namespace ns2_capture_this_byval { 239*a07aba5dSTimm Baeder struct S { 240*a07aba5dSTimm Baeder int s; 241*a07aba5dSTimm Baeder constexpr S(int s) : s{s} { } 242*a07aba5dSTimm Baeder constexpr auto f(S o) { 243*a07aba5dSTimm Baeder return [*this,o] (auto a) { return s + o.s + a.s; }; 244*a07aba5dSTimm Baeder } 245*a07aba5dSTimm Baeder }; 246*a07aba5dSTimm Baeder 247*a07aba5dSTimm Baeder constexpr auto L = S{5}.f(S{10}); 248*a07aba5dSTimm Baeder static_assert(L(S{100}) == 115, ""); 249*a07aba5dSTimm Baeder } // end test_captures_1::ns2_capture_this_byval 250*a07aba5dSTimm Baeder 251*a07aba5dSTimm Baeder namespace CaptureDefaults { 252*a07aba5dSTimm Baeder struct S { 253*a07aba5dSTimm Baeder int x; 254*a07aba5dSTimm Baeder }; 255*a07aba5dSTimm Baeder 256*a07aba5dSTimm Baeder constexpr auto f = [x = S{10}]() { 257*a07aba5dSTimm Baeder return x.x; 258*a07aba5dSTimm Baeder }; 259*a07aba5dSTimm Baeder static_assert(f() == 10, ""); 260*a07aba5dSTimm Baeder 261*a07aba5dSTimm Baeder constexpr auto f2 = [x = 3]() { 262*a07aba5dSTimm Baeder return x; 263*a07aba5dSTimm Baeder }; 264*a07aba5dSTimm Baeder static_assert(f2() == 3, ""); 265*a07aba5dSTimm Baeder } 266*a07aba5dSTimm Baeder 267*a07aba5dSTimm Baeder constexpr auto t4 = ([x=42]() consteval { return x; }()); 268*a07aba5dSTimm Baeder static_assert(t4 == 42, ""); 269*a07aba5dSTimm Baeder 270*a07aba5dSTimm Baeder namespace InvalidCapture { 271*a07aba5dSTimm Baeder 272*a07aba5dSTimm Baeder int &f(int *p); 273*a07aba5dSTimm Baeder char &f(...); 274*a07aba5dSTimm Baeder void g() { 275*a07aba5dSTimm Baeder int n = -1; // both-note {{declared here}} 276*a07aba5dSTimm Baeder [=] { 277*a07aba5dSTimm Baeder int arr[n]; // both-warning {{variable length arrays in C++ are a Clang extension}} \ 278*a07aba5dSTimm Baeder both-note {{read of non-const variable 'n' is not allowed in a constant expression}} 279*a07aba5dSTimm Baeder } (); 280*a07aba5dSTimm Baeder } 281*a07aba5dSTimm Baeder } 282*a07aba5dSTimm Baeder 283*a07aba5dSTimm Baeder constexpr int fn() { 284*a07aba5dSTimm Baeder int Capture = 42; 285*a07aba5dSTimm Baeder return [=]() constexpr { return Capture; }(); 286*a07aba5dSTimm Baeder } 287*a07aba5dSTimm Baeder static_assert(fn() == 42, ""); 288