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