Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / test / AST / Interp / lambda.cpp
blobf8400898acc0c05f07a174ee325e0e04adc71ce8
1 // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify -std=c++20 %s
2 // RUN: %clang_cc1 -verify=ref -std=c++20 %s
4 constexpr int a = 12;
5 constexpr int f = [c = a]() { return c; }();
6 static_assert(f == a);
9 constexpr int inc() {
10 int a = 10;
11 auto f = [&a]() {
12 ++a;
15 f();f();
17 return a;
19 static_assert(inc() == 12);
21 constexpr int add(int a, int b) {
22 auto doIt = [a, b](int c) {
23 return a + b + c;
26 return doIt(2);
28 static_assert(add(4, 5) == 11);
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; };
36 return bar() + bar2() + c;
39 return doIt(2);
41 static_assert(add2(4, 5) == 11);
44 constexpr int div(int a, int b) {
45 auto f = [=]() {
46 return a / b; // expected-note {{division by zero}} \
47 // ref-note {{division by zero}}
50 return f(); // expected-note {{in call to '&f->operator()()'}} \
51 // ref-note {{in call to 'f.operator()()'}}
53 static_assert(div(8, 2) == 4);
54 static_assert(div(8, 0) == 4); // expected-error {{not an integral constant expression}} \
55 // expected-note {{in call to 'div(8, 0)'}} \
56 // ref-error {{not an integral constant expression}} \
57 // ref-note {{in call to 'div(8, 0)'}}
60 struct F {
61 float f;
64 constexpr float captureStruct() {
65 F someF = {1.0};
67 auto p = [someF]() {
68 return someF.f;
71 return p();
74 static_assert(captureStruct() == 1.0);
77 int constexpr FunCase() {
78 return [x = 10] {
79 decltype(x) y; // type int b/c not odr use
80 // refers to original init-capture
81 auto &z = x; // type const int & b/c odr use
82 // refers to lambdas copy of x
83 y = 10; // Ok
84 //z = 10; // Ill-formed
85 return y;
86 }();
89 constexpr int WC = FunCase();
92 namespace LambdaParams {
93 template<typename T>
94 constexpr void callThis(T t) {
95 return t();
98 constexpr int foo() {
99 int a = 0;
100 auto f = [&a]() { ++a; };
102 callThis(f);
104 return a;
106 static_assert(foo() == 1);
109 namespace StaticInvoker {
110 constexpr int sv1(int i) {
111 auto l = []() { return 12; };
112 int (*fp)() = l;
113 return fp();
115 static_assert(sv1(12) == 12);
117 constexpr int sv2(int i) {
118 auto l = [](int m, float f, void *A) { return m; };
119 int (*fp)(int, float, void*) = l;
120 return fp(i, 4.0f, nullptr);
122 static_assert(sv2(12) == 12);
124 constexpr int sv3(int i) {
125 auto l = [](int m, const int &n) { return m; };
126 int (*fp)(int, const int &) = l;
127 return fp(i, 3);
129 static_assert(sv3(12) == 12);
131 constexpr int sv4(int i) {
132 auto l = [](int &m) { return m; };
133 int (*fp)(int&) = l;
134 return fp(i);
136 static_assert(sv4(12) == 12);
138 constexpr int sv5(int i) {
139 struct F { int a; float f; };
140 auto l = [](int m, F f) { return m; };
141 int (*fp)(int, F) = l;
142 return fp(i, F{12, 14.0});
144 static_assert(sv5(12) == 12);
146 constexpr int sv6(int i) {
147 struct F { int a;
148 constexpr F(int a) : a(a) {}
151 auto l = [](int m) { return F(12); };
152 F (*fp)(int) = l;
153 F f = fp(i);
155 return fp(i).a;
157 static_assert(sv6(12) == 12);
160 namespace LambdasAsParams {
161 template<typename F>
162 constexpr auto call(F f) {
163 return f();
165 static_assert(call([](){ return 1;}) == 1);
166 static_assert(call([](){ return 2;}) == 2);
169 constexpr unsigned L = call([](){ return 12;});
170 static_assert(L == 12);
173 constexpr float heh() {
174 auto a = []() {
175 return 1.0;
178 return static_cast<float>(a());
180 static_assert(heh() == 1.0);
183 namespace ThisCapture {
184 class Foo {
185 public:
186 int b = 32;
187 int a;
189 constexpr Foo() : a([this](){ return b + 1;}()) {}
191 constexpr int Aplus2() const {
192 auto F = [this]() {
193 return a + 2;
196 return F();
199 constexpr Foo F;
200 static_assert(F.a == 33, "");
201 static_assert(F.Aplus2() == (33 + 2), "");