blob: dd5063cb29c5b7ac7f64f02b8f37274f6b839a6b [file] [log] [blame]
Corentin Jabot86982622023-07-10 08:54:15 +02001// RUN: %clang_cc1 -std=c++2a -Wno-unused-value %s -verify
2// RUN: %clang_cc1 -std=c++2b -Wno-unused-value %s -verify
Corentin Jabot46768852023-05-08 12:18:43 +02003
4consteval int id(int i) { return i; }
5constexpr char id(char c) { return c; }
6
7template <typename T>
8constexpr int f(T t) { // expected-note {{declared here}}
9 return t + id(t); // expected-note 2{{'f<int>' is an immediate function because its body contains a call to a consteval function 'id' and that call is not a constant expression}}
10}
11
12namespace examples {
13
14auto a = &f<char>; // ok, f<char> is not an immediate function
15auto b = &f<int>; // expected-error {{cannot take address of immediate function 'f<int>' outside of an immediate invocation}}
16
17static_assert(f(3) == 6); // ok
18
19template <typename T>
20constexpr int g(T t) { // g<int> is not an immediate function
21 return t + id(42); // because id(42) is already a constant
22}
23
24template <typename T, typename F>
25constexpr bool is_not(T t, F f) {
26 return not f(t);
27}
28
29consteval bool is_even(int i) { return i % 2 == 0; }
30
31static_assert(is_not(5, is_even));
32
33int x = 0; // expected-note {{declared here}}
34
35template <typename T>
36constexpr T h(T t = id(x)) { // expected-note {{read of non-const variable 'x' is not allowed in a constant expression}} \
Corentin Jabot86982622023-07-10 08:54:15 +020037 // expected-note {{'hh<int>' is an immediate function because its body contains a call to a consteval function 'id' and that call is not a constant expression}}
Corentin Jabot46768852023-05-08 12:18:43 +020038 return t;
39}
40
41template <typename T>
42constexpr T hh() { // hh<int> is an immediate function
43 [[maybe_unused]] auto x = h<T>();
44 return h<T>();
45}
46
47int i = hh<int>(); // expected-error {{call to immediate function 'examples::hh<int>' is not a constant expression}} \
Takuya Shimizue90f4fc2023-07-31 17:05:56 +090048 // expected-note {{in call to 'hh<int>()'}}
Corentin Jabot46768852023-05-08 12:18:43 +020049
50struct A {
51 int x;
52 int y = id(x);
53};
54
55template <typename T>
56constexpr int k(int) {
57 return A(42).y;
58}
59
60}
61
62namespace nested {
63
64template <typename T>
65constexpr int fdupe(T t) {
66 return id(t);
67}
68
69struct a {
70 constexpr a(int) { }
71};
72
73a aa(fdupe<int>((f<int>(7))));
74
75template <typename T>
76constexpr int foo(T t); // expected-note {{declared here}}
77
78a bb(f<int>(foo<int>(7))); // expected-error{{call to immediate function 'f<int>' is not a constant expression}} \
79 // expected-note{{undefined function 'foo<int>' cannot be used in a constant expression}}
80
81}
82
83namespace e2{
84template <typename T>
85constexpr int f(T t);
86auto a = &f<char>;
87auto b = &f<int>;
88}
89
90namespace forward_declare_constexpr{
91template <typename T>
92constexpr int f(T t);
93
94auto a = &f<char>;
95auto b = &f<int>;
96
97template <typename T>
98constexpr int f(T t) {
99 return id(0);
100}
101}
102
103namespace forward_declare_consteval{
104template <typename T>
Tom Honermann256a0b22023-09-12 10:30:59 -0700105constexpr int f(T t);
Corentin Jabot46768852023-05-08 12:18:43 +0200106
107auto a = &f<char>;
108auto b = &f<int>; // expected-error {{immediate function 'f<int>' used before it is defined}} \
109 // expected-note {{in instantiation of function template specialization}}
110
111template <typename T>
Tom Honermann256a0b22023-09-12 10:30:59 -0700112constexpr int f(T t) { // expected-note {{'f<int>' defined here}}
Corentin Jabot46768852023-05-08 12:18:43 +0200113 return id(t); // expected-note {{'f<int>' is an immediate function because its body contains a call to a consteval function 'id' and that call is not a constant expression}}
114}
115}
116
117namespace constructors {
118consteval int f(int) {
119 return 0;
120}
121struct S {
122 constexpr S(auto i) {
123 f(i);
124 }
125};
126constexpr void g(auto i) {
127 [[maybe_unused]] S s{i};
128}
129void test() {
130 g(0);
131}
132}
133
134namespace aggregate {
135consteval int f(int);
136struct S{
137 int a = 0;
138 int b = f(a);
139};
140
141constexpr bool test(auto i) {
142 S s{i};
143 return s.b == 2 *i;
144}
145consteval int f(int i) {
146 return 2 * i;
147}
148
149void test() {
150 static_assert(test(42));
151}
152
153}
154
155namespace ConstevalConstructor{
156int x = 0; // expected-note {{declared here}}
157struct S {
158 consteval S(int) {};
159};
160constexpr int g(auto t) {
161 S s(t); // expected-note {{'g<int>' is an immediate function because its body contains a call to a consteval constructor 'S' and that call is not a constant expression}}
162 return 0;
163}
164int i = g(x); // expected-error {{call to immediate function 'ConstevalConstructor::g<int>' is not a constant expression}} \
165 // expected-note {{read of non-const variable 'x' is not allowed in a constant expression}}
166}
Corentin Jabot86982622023-07-10 08:54:15 +0200167
168
169
170namespace Aggregate {
171consteval int f(int); // expected-note {{declared here}}
172struct S {
173 int x = f(42); // expected-note {{undefined function 'f' cannot be used in a constant expression}} \
174 // expected-note {{'immediate<int>' is an immediate function because its body contains a call to a consteval function 'f' and that call is not a constant expression}}
175};
176
177constexpr S immediate(auto) {
178 return S{};
179}
180
181void test_runtime() {
182 (void)immediate(0); // expected-error {{call to immediate function 'Aggregate::immediate<int>' is not a constant expression}} \
Takuya Shimizue90f4fc2023-07-31 17:05:56 +0900183 // expected-note {{in call to 'immediate<int>(0)'}}
Corentin Jabot86982622023-07-10 08:54:15 +0200184}
185consteval int f(int i) {
186 return i;
187}
188consteval void test() {
189 constexpr S s = immediate(0);
190 static_assert(s.x == 42);
191}
192}
193
194
195
196namespace GH63742 {
197void side_effect(); // expected-note {{declared here}}
198consteval int f(int x) {
199 if (!x) side_effect(); // expected-note {{non-constexpr function 'side_effect' cannot be used in a constant expression}}
200 return x;
201}
202struct SS {
203 int y = f(1); // Ok
204 int x = f(0); // expected-error {{call to consteval function 'GH63742::f' is not a constant expression}} \
205 // expected-note {{declared here}} \
206 // expected-note {{in call to 'f(0)'}}
207 SS();
208};
209SS::SS(){} // expected-note {{in the default initializer of 'x'}}
210
211consteval int f2(int x) {
Sam McCall880fa7f2023-09-27 18:41:11 +0200212 if (!__builtin_is_constant_evaluated()) side_effect();
Corentin Jabot86982622023-07-10 08:54:15 +0200213 return x;
214}
215struct S2 {
216 int x = f2(0);
217 constexpr S2();
218};
219
220constexpr S2::S2(){}
221S2 s = {};
222constinit S2 s2 = {};
223
224struct S3 {
225 int x = f2(0);
226 S3();
227};
228S3::S3(){}
229
230}
231
232namespace Defaulted {
233consteval int f(int x);
234struct SS {
235 int x = f(0);
236 SS() = default;
237};
238}
239
240namespace DefaultedUse{
241consteval int f(int x); // expected-note {{declared here}}
242struct SS {
243 int a = sizeof(f(0)); // Ok
244 int x = f(0); // expected-note {{undefined function 'f' cannot be used in a constant expression}}
245
246 SS() = default; // expected-note {{'SS' is an immediate constructor because the default initializer of 'x' contains a call to a consteval function 'f' and that call is not a constant expression}}
247};
248
249void test() {
250 [[maybe_unused]] SS s; // expected-error {{call to immediate function 'DefaultedUse::SS::SS' is not a constant expression}} \
251 // expected-note {{in call to 'SS()'}}
252}
253}
254
255namespace UserDefinedConstructors {
256consteval int f(int x) {
257 return x;
258}
259extern int NonConst; // expected-note 2{{declared here}}
260
261struct ConstevalCtr {
262 int y;
263 int x = f(y);
264 consteval ConstevalCtr(int yy)
265 : y(f(yy)) {}
266};
267
268ConstevalCtr c1(1);
269ConstevalCtr c2(NonConst);
270// expected-error@-1 {{call to consteval function 'UserDefinedConstructors::ConstevalCtr::ConstevalCtr' is not a constant expression}} \
271// expected-note@-1 {{read of non-const variable 'NonConst' is not allowed in a constant expression}}
272
273struct ImmediateEscalating {
274 int y;
275 int x = f(y);
276 template<typename T>
277 constexpr ImmediateEscalating(T yy) // expected-note {{ImmediateEscalating<int>' is an immediate constructor because the initializer of 'y' contains a call to a consteval function 'f' and that call is not a constant expression}}
278 : y(f(yy)) {}
279};
280
281ImmediateEscalating c3(1);
282ImmediateEscalating c4(NonConst);
283// expected-error@-1 {{call to immediate function 'UserDefinedConstructors::ImmediateEscalating::ImmediateEscalating<int>' is not a constant expression}} \
284// expected-note@-1 {{read of non-const variable 'NonConst' is not allowed in a constant expression}}
285
286
287struct NonEscalating {
288 int y;
289 int x = f(this->y); // expected-error {{call to consteval function 'UserDefinedConstructors::f' is not a constant expression}} \
290 // expected-note {{declared here}} \
291 // expected-note {{use of 'this' pointer is only allowed within the evaluation of a call to a 'constexpr' member function}}
292 constexpr NonEscalating(int yy) : y(yy) {} // expected-note {{in the default initializer of 'x'}}
293};
294NonEscalating s = {1};
295
296}
297
298namespace AggregateInit {
299
300consteval int f(int x) {
301 return x;
302}
303
304struct S {
305 int i;
306 int j = f(i);
307};
308
309constexpr S test(auto) {
310 return {};
311}
312
313S s = test(0);
314
315}
316
317namespace GlobalAggregateInit {
318
319consteval int f(int x) {
320 return x;
321}
322
323struct S {
324 int i;
325 int j = f(i); // expected-error {{call to consteval function 'GlobalAggregateInit::f' is not a constant expression}} \
326 // expected-note {{implicit use of 'this' pointer is only allowed within the evaluation of a call to a 'constexpr' member function}} \
327 // expected-note {{declared here}}
328};
329
330S s(0); // expected-note {{in the default initializer of 'j'}}
331
332}
cor3ntincacdb902023-09-19 00:24:43 +0200333
cor3ntin0677d7c2023-09-19 23:41:51 +0200334namespace GH65985 {
Sam McCall880fa7f2023-09-27 18:41:11 +0200335consteval int invalid(); // expected-note 2{{declared here}}
cor3ntin0677d7c2023-09-19 23:41:51 +0200336constexpr int escalating(auto) {
337 return invalid();
Sam McCall880fa7f2023-09-27 18:41:11 +0200338 // expected-note@-1 {{'escalating<int>' is an immediate function because its body contains a call to a consteval function 'invalid' and that call is not a constant expression}}
339 // expected-note@-2 2{{undefined function 'invalid' cannot be used in a constant expression}}
cor3ntin0677d7c2023-09-19 23:41:51 +0200340}
341struct S {
Sam McCall880fa7f2023-09-27 18:41:11 +0200342 static constexpr int a = escalating(0); // expected-note 2{{in call to}}
343 // expected-error@-1 {{call to immediate function 'GH65985::escalating<int>' is not a constant expression}}
344 // expected-error@-2 {{constexpr variable 'a' must be initialized by a constant expression}}
cor3ntin0677d7c2023-09-19 23:41:51 +0200345};
346
347}
348
cor3ntincacdb902023-09-19 00:24:43 +0200349namespace GH66324 {
350
351consteval int allocate(); // expected-note 2{{declared here}}
352
353struct _Vector_base {
354 int b = allocate(); // expected-note 2{{undefined function 'allocate' cannot be used in a constant expression}} \
355 // expected-error {{call to consteval function 'GH66324::allocate' is not a constant expression}} \
356 // expected-note {{declared here}}
357};
358
359template <typename>
360struct vector : _Vector_base {
361 constexpr vector()
362 // expected-note@-1 {{'vector' is an immediate constructor because its body contains a call to a consteval function 'allocate' and that call is not a constant expression}}
363 : _Vector_base{} {} // expected-note {{in the default initializer of 'b'}}
364};
365
366vector<void> v{};
367// expected-error@-1 {{call to immediate function 'GH66324::vector<void>::vector' is not a constant expression}}
368// expected-note@-2 {{in call to 'vector()'}}
369
370}
cor3ntinbaf6bd32024-02-21 20:53:44 +0100371
372
373namespace GH82258 {
374
375template <class R, class Pred>
376constexpr auto none_of(R&& r, Pred pred) -> bool { return true; }
377
378struct info { int value; };
379consteval auto is_invalid(info i) -> bool { return false; }
380constexpr info types[] = { {1}, {3}, {5}};
381
382static_assert(none_of(
383 types,
384 +[](info i) consteval {
385 return is_invalid(i);
386 }
387));
388
389static_assert(none_of(
390 types,
391 []{
392 return is_invalid;
393 }()
394));
395
396}
Daniel M. Katz443377a2024-05-09 03:22:11 -0400397
398#if __cplusplus >= 202302L
399namespace lvalue_to_rvalue_init_from_heap {
400
401struct S {
402 int *value;
403 constexpr S(int v) : value(new int {v}) {} // expected-note 2 {{heap allocation performed here}}
404 constexpr ~S() { delete value; }
405};
406consteval S fn() { return S(5); }
407int fn2() { return 2; } // expected-note {{declared here}}
408
409constexpr int a = *fn().value;
410constinit int b = *fn().value;
411const int c = *fn().value;
412int d = *fn().value;
413
414constexpr int e = *fn().value + fn2(); // expected-error {{must be initialized by a constant expression}} \
415 // expected-error {{call to consteval function 'lvalue_to_rvalue_init_from_heap::fn' is not a constant expression}} \
416 // expected-note {{non-constexpr function 'fn2'}} \
417 // expected-note {{pointer to heap-allocated object}}
418
419int f = *fn().value + fn2(); // expected-error {{call to consteval function 'lvalue_to_rvalue_init_from_heap::fn' is not a constant expression}} \
420 // expected-note {{pointer to heap-allocated object}}
421}
422#endif
cor3ntinc4e9e412024-05-13 16:04:20 +0200423
424
425#if __cplusplus >= 202302L
426
427namespace GH91509 {
428
429consteval int f(int) { return 0; }
430
431template<typename T>
432constexpr int g(int x) {
433 if consteval {
434 return f(x);
435 }
436 if !consteval {}
437 else {
438 return f(x);
439 }
440 return 1;
441}
442
443int h(int x) {
444 return g<void>(x);
445}
446}
447
448#endif
cor3ntindd32c3d2024-05-23 17:53:07 +0200449
450
451namespace GH91308 {
452 constexpr void f(auto) {
453 static_assert(false);
454 }
455 using R1 = decltype(&f<int>);
456}
cor3ntin3417ff62024-06-18 15:40:25 +0200457
458namespace GH94935 {
459
460consteval void f(int) {}
461consteval void undef(int); // expected-note {{declared here}}
462
463template<typename T>
464struct G {
465 void g() {
466 GH94935::f(T::fn());
467 GH94935::f(T::undef2()); // expected-error {{call to consteval function 'GH94935::f' is not a constant expression}} \
468 // expected-note {{undefined function 'undef2' cannot be used in a constant expression}}
469 GH94935::undef(T::fn()); // expected-error {{call to consteval function 'GH94935::undef' is not a constant expression}} \
470 // expected-note {{undefined function 'undef' cannot be used in a constant expression}}
471 }
472};
473
474struct X {
475 static consteval int fn() { return 0; }
476 static consteval int undef2(); // expected-note {{declared here}}
477
478};
479
480void test() {
481 G<X>{}.g(); // expected-note {{instantiation}}
482}
483
484
485template<typename T>
486void g() {
487 auto l = []{
488 ::f(T::fn());
489 };
490}
491
492struct Y {
493 static int fn();
494};
495
496template void g<Y>();
497
498}
cor3ntin213e03c2025-01-22 22:00:17 +0100499
500namespace GH112677 {
501
502class ConstEval {
503 public:
504 consteval ConstEval(int); // expected-note 2{{declared here}}
505};
506
507struct TemplateCtor {
508 ConstEval val;
509 template <class Anything = int> constexpr
510 TemplateCtor(int arg) : val(arg) {} // expected-note {{undefined constructor 'ConstEval'}}
511};
512struct C : TemplateCtor {
513 using TemplateCtor::TemplateCtor; // expected-note {{in call to 'TemplateCtor<int>(0)'}}
514};
515
516C c(0); // expected-note{{in implicit initialization for inherited constructor of 'C'}}
517// expected-error@-1 {{call to immediate function 'GH112677::C::TemplateCtor' is not a constant expression}}
518
519struct SimpleCtor { constexpr SimpleCtor(int) {}};
520struct D : SimpleCtor {
521 int y = 10;
522 ConstEval x = y; // expected-note {{undefined constructor 'ConstEval'}}
523 using SimpleCtor::SimpleCtor;
524 //expected-note@-1 {{'SimpleCtor' is an immediate constructor because the default initializer of 'x' contains a call to a consteval constructor 'ConstEval' and that call is not a constant expression}}
525};
526
527D d(0); // expected-note {{in implicit initialization for inherited constructor of 'D'}}
528// expected-error@-1 {{call to immediate function 'GH112677::D::SimpleCtor' is not a constant expression}}
529
530}
cor3ntin561132e2025-01-27 15:50:51 +0100531
532namespace GH123405 {
533
534consteval void fn() {}
535
536template <typename>
cor3ntin19f05242025-01-27 18:30:51 +0100537constexpr auto tfn(int) {
cor3ntin561132e2025-01-27 15:50:51 +0100538 auto p = &fn; // expected-note {{'tfn<int>' is an immediate function because its body evaluates the address of a consteval function 'fn'}}
cor3ntin19f05242025-01-27 18:30:51 +0100539 return p;
cor3ntin561132e2025-01-27 15:50:51 +0100540}
541
cor3ntin19f05242025-01-27 18:30:51 +0100542void g() {
cor3ntin561132e2025-01-27 15:50:51 +0100543 int a; // expected-note {{declared here}}
cor3ntin19f05242025-01-27 18:30:51 +0100544 tfn<int>(a); // expected-error {{call to immediate function 'GH123405::tfn<int>' is not a constant expression}}\
545 // expected-note {{read of non-const variable 'a' is not allowed in a constant expression}}
cor3ntin561132e2025-01-27 15:50:51 +0100546}
cor3ntina85b2dc2025-01-27 21:30:29 +0100547} // namespace GH123405
cor3ntin561132e2025-01-27 15:50:51 +0100548
cor3ntina85b2dc2025-01-27 21:30:29 +0100549namespace GH118000 {
550consteval int baz() { return 0;}
551struct S {
552 int mSize = baz();
553};
554
555consteval void bar() {
556 S s;
cor3ntin561132e2025-01-27 15:50:51 +0100557}
cor3ntina85b2dc2025-01-27 21:30:29 +0100558
559void foo() {
560 S s;
561}
562} // namespace GH118000
cor3ntin820c6ac2025-01-28 15:18:38 +0100563
564namespace GH119046 {
565
566template <typename Cls> constexpr auto tfn(int) {
567 return (unsigned long long)(&Cls::sfn);
568 //expected-note@-1 {{'tfn<GH119046::S>' is an immediate function because its body evaluates the address of a consteval function 'sfn'}}
569};
570struct S { static consteval void sfn() {} };
571
572int f() {
573 int a = 0; // expected-note{{declared here}}
574 return tfn<S>(a);
575 //expected-error@-1 {{call to immediate function 'GH119046::tfn<GH119046::S>' is not a constant expression}}
576 //expected-note@-2 {{read of non-const variable 'a' is not allowed in a constant expression}}
577}
578}