288 lines · cpp
1// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify=expected,both -std=c++20 %s2// RUN: %clang_cc1 -verify=ref,both -std=c++20 %s3 4constexpr int a = 12;5constexpr int f = [c = a]() { return c; }();6static_assert(f == a);7 8 9constexpr int inc() {10 int a = 10;11 auto f = [&a]() {12 ++a;13 };14 15 f();f();16 17 return a;18}19static_assert(inc() == 12);20 21constexpr 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}28static_assert(add(4, 5) == 11);29 30 31constexpr 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}41static_assert(add2(4, 5) == 11);42 43 44constexpr 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}51static_assert(div(8, 2) == 4);52static_assert(div(8, 0) == 4); // both-error {{not an integral constant expression}} \53 // both-note {{in call to 'div(8, 0)'}}54 55 56struct F {57 float f;58};59 60constexpr float captureStruct() {61 F someF = {1.0};62 63 auto p = [someF]() {64 return someF.f;65 };66 67 return p();68}69 70static_assert(captureStruct() == 1.0);71 72 73int constexpr FunCase() {74 return [x = 10] {75 decltype(x) y; // type int b/c not odr use76 // refers to original init-capture77 auto &z = x; // type const int & b/c odr use78 // refers to lambdas copy of x79 y = 10; // Ok80 //z = 10; // Ill-formed81 return y;82 }();83}84 85constexpr int WC = FunCase();86 87 88namespace 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 105namespace 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 169namespace 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 192namespace 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 213namespace 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 225namespace 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 238namespace 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_byval250 251namespace 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 267constexpr auto t4 = ([x=42]() consteval { return x; }());268static_assert(t4 == 42, "");269 270namespace 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 283constexpr int fn() {284 int Capture = 42;285 return [=]() constexpr { return Capture; }();286}287static_assert(fn() == 42, "");288