1 // RUN: %clang_cc1 -std=c++2a -emit-llvm-only -Wno-unused-value %s -verify
2
3 typedef __SIZE_TYPE__ size_t;
4
5 namespace basic_sema {
6
f1(int i)7 consteval int f1(int i) {
8 return i;
9 }
10
f2(int i)11 consteval constexpr int f2(int i) {
12 //expected-error@-1 {{cannot combine}}
13 return i;
14 }
15
__anonee0ef89f0102(int i) 16 constexpr auto l_eval = [](int i) consteval {
17 // expected-note@-1+ {{declared here}}
18
19 return i;
20 };
21
f3(int i)22 constexpr consteval int f3(int i) {
23 //expected-error@-1 {{cannot combine}}
24 return i;
25 }
26
27 struct A {
f1basic_sema::A28 consteval int f1(int i) const {
29 // expected-note@-1 {{declared here}}
30 return i;
31 }
32 consteval A(int i);
33 consteval A() = default;
34 consteval ~A() = default; // expected-error {{destructor cannot be declared consteval}}
35 };
36
37 consteval struct B {}; // expected-error {{struct cannot be marked consteval}}
38
39 consteval typedef B b; // expected-error {{typedef cannot be consteval}}
40
redecl()41 consteval int redecl() {return 0;} // expected-note {{previous declaration is here}}
redecl()42 constexpr int redecl() {return 0;} // expected-error {{constexpr declaration of 'redecl' follows consteval declaration}}
43
44 consteval int i = 0; // expected-error {{consteval can only be used in function declarations}}
45
46 consteval int; // expected-error {{consteval can only be used in function declarations}}
47
f1()48 consteval int f1() {} // expected-error {{no return statement in consteval function}}
49
50 struct C {
Cbasic_sema::C51 C() {}
~Cbasic_sema::C52 ~C() {}
53 };
54
55 struct D {
56 C c;
57 consteval D() = default; // expected-error {{cannot be consteval}}
58 consteval ~D() = default; // expected-error {{destructor cannot be declared consteval}}
59 };
60
61 struct E : C {
~Ebasic_sema::E62 consteval ~E() {} // expected-error {{cannot be declared consteval}}
63 };
64 }
65
main()66 consteval int main() { // expected-error {{'main' is not allowed to be declared consteval}}
67 return 0;
68 }
69
f_eval(int i)70 consteval int f_eval(int i) {
71 // expected-note@-1+ {{declared here}}
72 return i;
73 }
74
75 namespace taking_address {
76
77 using func_type = int(int);
78
79 func_type* p1 = (&f_eval);
80 // expected-error@-1 {{take address}}
81 func_type* p7 = __builtin_addressof(f_eval);
82 // expected-error@-1 {{take address}}
83
84 auto p = f_eval;
85 // expected-error@-1 {{take address}}
86
87 auto m1 = &basic_sema::A::f1;
88 // expected-error@-1 {{take address}}
89 auto l1 = &decltype(basic_sema::l_eval)::operator();
90 // expected-error@-1 {{take address}}
91
f(int i)92 consteval int f(int i) {
93 // expected-note@-1+ {{declared here}}
94 return i;
95 }
96
97 auto ptr = &f;
98 // expected-error@-1 {{take address}}
99
f1()100 auto f1() {
101 return &f;
102 // expected-error@-1 {{take address}}
103 }
104
105 }
106
107 namespace invalid_function {
108
109 struct A {
110 consteval void *operator new(size_t count);
111 // expected-error@-1 {{'operator new' cannot be declared consteval}}
112 consteval void *operator new[](size_t count);
113 // expected-error@-1 {{'operator new[]' cannot be declared consteval}}
114 consteval void operator delete(void* ptr);
115 // expected-error@-1 {{'operator delete' cannot be declared consteval}}
116 consteval void operator delete[](void* ptr);
117 // expected-error@-1 {{'operator delete[]' cannot be declared consteval}}
~Ainvalid_function::A118 consteval ~A() {}
119 // expected-error@-1 {{destructor cannot be declared consteval}}
120 };
121
122 }
123
124 namespace nested {
f()125 consteval int f() {
126 return 0;
127 }
128
f1(...)129 consteval int f1(...) {
130 return 1;
131 }
132
133 enum E {};
134
135 using T = int(&)();
136
operator +(E,int (* a)())137 consteval auto operator+ (E, int(*a)()) {
138 return 0;
139 }
140
d()141 void d() {
142 auto i = f1(E() + &f);
143 }
144
__anonee0ef89f0202(auto) 145 auto l0 = [](auto) consteval {
146 return 0;
147 };
148
149 int i0 = l0(&f1);
150
151 int i1 = f1(l0(4));
152
153 int i2 = f1(&f1, &f1, &f1, &f1, &f1, &f1, &f1);
154
155 int i3 = f1(f1(f1(&f1, &f1), f1(&f1, &f1), f1(f1(&f1, &f1), &f1)));
156
157 }
158
159 namespace user_defined_literal {
160
operator ""_test(unsigned long long i)161 consteval int operator"" _test(unsigned long long i) {
162 // expected-note@-1+ {{declared here}}
163 return 0;
164 }
165
166 int i = 0_test;
167
168 auto ptr = &operator"" _test;
169 // expected-error@-1 {{take address}}
170
operator ""_test1(unsigned long long i)171 consteval auto operator"" _test1(unsigned long long i) {
172 return &f_eval;
173 }
174
175 auto i1 = 0_test1; // expected-error {{is not a constant expression}}
176 // expected-note@-1 {{is not a constant expression}}
177
178 }
179
180 namespace return_address {
181
f()182 consteval int f() {
183 // expected-note@-1 {{declared here}}
184 return 0;
185 }
186
ret1(int i)187 consteval int(*ret1(int i))() {
188 return &f;
189 }
190
191 auto ptr = ret1(0);
192 // expected-error@-1 {{is not a constant expression}}
193 // expected-note@-2 {{pointer to a consteval}}
194
195 struct A {
freturn_address::A196 consteval int f(int) {
197 // expected-note@-1+ {{declared here}}
198 return 0;
199 }
200 };
201
202 using mem_ptr_type = int (A::*)(int);
203
204 template<mem_ptr_type ptr>
205 struct C {};
206
207 C<&A::f> c;
208 // expected-error@-1 {{is not a constant expression}}
209 // expected-note@-2 {{pointer to a consteval}}
210
ret2()211 consteval mem_ptr_type ret2() {
212 return &A::f;
213 }
214
215 C<ret2()> c1;
216 // expected-error@-1 {{is not a constant expression}}
217 // expected-note@-2 {{pointer to a consteval}}
218
219 }
220
221 namespace context {
222
223 int g_i;
224 // expected-note@-1 {{declared here}}
225
f(int)226 consteval int f(int) {
227 return 0;
228 }
229
230 constexpr int c_i = 0;
231
232 int t1 = f(g_i);
233 // expected-error@-1 {{is not a constant expression}}
234 // expected-note@-2 {{read of non-const variable}}
235 int t3 = f(c_i);
236
f_c(int i)237 constexpr int f_c(int i) {
238 // expected-note@-1 {{declared here}}
239 int t = f(i);
240 // expected-error@-1 {{is not a constant expression}}
241 // expected-note@-2 {{read of non-const variable}}
242 return f(0);
243 }
244
f_eval(int i)245 consteval int f_eval(int i) {
246 return f(i);
247 }
248
__anonee0ef89f0302(int i) 249 auto l0 = [](int i) consteval {
250 return f(i);
251 };
252
__anonee0ef89f0402(int i) 253 auto l1 = [](int i) constexpr {
254 // expected-note@-1 {{declared here}}
255 int t = f(i);
256 // expected-error@-1 {{is not a constant expression}}
257 // expected-note@-2 {{read of non-const variable}}
258 return f(0);
259 };
260
261 }
262
263 namespace std {
264
265 template <typename T> struct remove_reference { using type = T; };
266 template <typename T> struct remove_reference<T &> { using type = T; };
267 template <typename T> struct remove_reference<T &&> { using type = T; };
268
269 template <typename T>
move(T && t)270 constexpr typename std::remove_reference<T>::type&& move(T &&t) noexcept {
271 return static_cast<typename std::remove_reference<T>::type &&>(t);
272 }
273
274 }
275
276 namespace temporaries {
277
278 struct A {
ret_itemporaries::A279 consteval int ret_i() const { return 0; }
ret_atemporaries::A280 consteval A ret_a() const { return A{}; }
~Atemporaries::A281 constexpr ~A() { }
282 };
283
by_value_a(A a)284 consteval int by_value_a(A a) { return a.ret_i(); }
285
const_a_ref(const A & a)286 consteval int const_a_ref(const A &a) {
287 return a.ret_i();
288 }
289
rvalue_ref(const A && a)290 consteval int rvalue_ref(const A &&a) {
291 return a.ret_i();
292 }
293
to_lvalue_ref(const A && a)294 consteval const A &to_lvalue_ref(const A &&a) {
295 return a;
296 }
297
test()298 void test() {
299 constexpr A a {};
300 { int k = A().ret_i(); }
301 { A k = A().ret_a(); }
302 { A k = to_lvalue_ref(A()); }// expected-error {{is not a constant expression}}
303 // expected-note@-1 {{is not a constant expression}} expected-note@-1 {{temporary created here}}
304 { A k = to_lvalue_ref(A().ret_a()); } // expected-error {{is not a constant expression}}
305 // expected-note@-1 {{is not a constant expression}} expected-note@-1 {{temporary created here}}
306 { int k = A().ret_a().ret_i(); }
307 { int k = by_value_a(A()); }
308 { int k = const_a_ref(A()); }
309 { int k = const_a_ref(a); }
310 { int k = rvalue_ref(A()); }
311 { int k = rvalue_ref(std::move(a)); }
312 { int k = const_a_ref(A().ret_a()); }
313 { int k = const_a_ref(to_lvalue_ref(A().ret_a())); }
314 { int k = const_a_ref(to_lvalue_ref(std::move(a))); }
315 { int k = by_value_a(A().ret_a()); }
316 { int k = by_value_a(to_lvalue_ref(std::move(a))); }
317 { int k = (A().ret_a(), A().ret_i()); }
318 { int k = (const_a_ref(A().ret_a()), A().ret_i()); }//
319 }
320
321 }
322
323 namespace alloc {
324
f()325 consteval int f() {
326 int *A = new int(0);
327 // expected-note@-1+ {{allocation performed here was not deallocated}}
328 return *A;
329 }
330
331 int i1 = f(); // expected-error {{is not a constant expression}}
332
333 struct A {
334 int* p = new int(42);
335 // expected-note@-1+ {{heap allocation performed here}}
ret_ialloc::A336 consteval int ret_i() const { return p ? *p : 0; }
ret_aalloc::A337 consteval A ret_a() const { return A{}; }
~Aalloc::A338 constexpr ~A() { delete p; }
339 };
340
by_value_a(A a)341 consteval int by_value_a(A a) { return a.ret_i(); }
342
const_a_ref(const A & a)343 consteval int const_a_ref(const A &a) {
344 return a.ret_i();
345 }
346
rvalue_ref(const A && a)347 consteval int rvalue_ref(const A &&a) {
348 return a.ret_i();
349 }
350
to_lvalue_ref(const A && a)351 consteval const A &to_lvalue_ref(const A &&a) {
352 return a;
353 }
354
test()355 void test() {
356 constexpr A a{ nullptr };
357 { int k = A().ret_i(); }
358 { A k = A().ret_a(); } // expected-error {{is not a constant expression}}
359 // expected-note@-1 {{is not a constant expression}}
360 { A k = to_lvalue_ref(A()); } // expected-error {{is not a constant expression}}
361 // expected-note@-1 {{is not a constant expression}} expected-note@-1 {{temporary created here}}
362 { A k = to_lvalue_ref(A().ret_a()); } // expected-error {{is not a constant expression}}
363 // expected-note@-1 {{is not a constant expression}} expected-note@-1 {{temporary created here}}
364 { int k = A().ret_a().ret_i(); }
365 { int k = by_value_a(A()); }
366 { int k = const_a_ref(A()); }
367 { int k = const_a_ref(a); }
368 { int k = rvalue_ref(A()); }
369 { int k = rvalue_ref(std::move(a)); }
370 { int k = const_a_ref(A().ret_a()); }
371 { int k = const_a_ref(to_lvalue_ref(A().ret_a())); }
372 { int k = const_a_ref(to_lvalue_ref(std::move(a))); }
373 { int k = by_value_a(A().ret_a()); }
374 { int k = by_value_a(to_lvalue_ref(static_cast<const A&&>(a))); }
375 { int k = (A().ret_a(), A().ret_i()); }// expected-error {{is not a constant expression}}
376 // expected-note@-1 {{is not a constant expression}}
377 { int k = (const_a_ref(A().ret_a()), A().ret_i()); }
378 }
379
380 }
381
382 namespace self_referencing {
383
384 struct S {
385 S* ptr = nullptr;
Sself_referencing::S386 constexpr S(int i) : ptr(this) {
387 if (this == ptr && i)
388 ptr = nullptr;
389 }
~Sself_referencing::S390 constexpr ~S() {}
391 };
392
f(int i)393 consteval S f(int i) {
394 return S(i);
395 }
396
test()397 void test() {
398 S s(1);
399 s = f(1);
400 s = f(0); // expected-error {{is not a constant expression}}
401 // expected-note@-1 {{is not a constant expression}} expected-note@-1 {{temporary created here}}
402 }
403
404 struct S1 {
405 S1* ptr = nullptr;
S1self_referencing::S1406 consteval S1(int i) : ptr(this) {
407 if (this == ptr && i)
408 ptr = nullptr;
409 }
~S1self_referencing::S1410 constexpr ~S1() {}
411 };
412
test1()413 void test1() {
414 S1 s(1);
415 s = S1(1);
416 s = S1(0); // expected-error {{is not a constant expression}}
417 // expected-note@-1 {{is not a constant expression}} expected-note@-1 {{temporary created here}}
418 }
419
420 }
421 namespace ctor {
422
f_eval()423 consteval int f_eval() { // expected-note+ {{declared here}}
424 return 0;
425 }
426
427 namespace std {
428 struct strong_ordering {
429 int n;
430 static const strong_ordering less, equal, greater;
431 };
432 constexpr strong_ordering strong_ordering::less = {-1};
433 constexpr strong_ordering strong_ordering::equal = {0};
434 constexpr strong_ordering strong_ordering::greater = {1};
435 constexpr bool operator!=(strong_ordering, int);
436 }
437
438 namespace override {
439 struct A {
440 virtual consteval void f(); // expected-note {{overridden}}
441 virtual void g(); // expected-note {{overridden}}
442 };
443 struct B : A {
444 consteval void f();
445 void g();
446 };
447 struct C : A {
448 void f(); // expected-error {{non-consteval function 'f' cannot override a consteval function}}
449 consteval void g(); // expected-error {{consteval function 'g' cannot override a non-consteval function}}
450 };
451
452 namespace implicit_equals_1 {
453 struct Y;
454 struct X {
455 std::strong_ordering operator<=>(const X&) const;
456 constexpr bool operator==(const X&) const;
457 virtual consteval bool operator==(const Y&) const; // expected-note {{here}}
458 };
459 struct Y : X {
460 std::strong_ordering operator<=>(const Y&) const = default;
461 // expected-error@-1 {{non-consteval function 'operator==' cannot override a consteval function}}
462 };
463 }
464
465 namespace implicit_equals_2 {
466 struct Y;
467 struct X {
468 constexpr std::strong_ordering operator<=>(const X&) const;
469 constexpr bool operator==(const X&) const;
470 virtual bool operator==(const Y&) const; // expected-note {{here}}
471 };
472 struct Y : X {
473 consteval std::strong_ordering operator<=>(const Y&) const = default;
474 // expected-error@-1 {{consteval function 'operator==' cannot override a non-consteval function}}
475 };
476 }
477 }
478
479 namespace operator_rewrite {
480 struct A {
operator <=>(const A &,const A &)481 friend consteval int operator<=>(const A&, const A&) { return 0; }
482 };
483 const bool k = A() < A();
484 static_assert(!k);
485
486 A a;
487 bool k2 = A() < a; // OK, does not access 'a'.
488
489 struct B {
operator <=>(const B & l,const B & r)490 friend consteval int operator<=>(const B &l, const B &r) { return r.n - l.n; } // expected-note {{read of }}
491 int n;
492 };
493 static_assert(B() >= B());
494 B b; // expected-note {{here}}
495 bool k3 = B() < b; // expected-error-re {{call to consteval function '{{.*}}::operator<=>' is not a constant expression}} expected-note {{in call}}
496 }
497
498 struct A {
499 int(*ptr)();
Actor::A500 consteval A(int(*p)() = nullptr) : ptr(p) {}
501 };
502
503 struct B {
504 int(*ptr)();
Bctor::B505 B() : ptr(nullptr) {}
Bctor::B506 consteval B(int(*p)(), int) : ptr(p) {}
507 };
508
test()509 void test() {
510 { A a; }
511 { A a(&f_eval); } // expected-error {{is not a constant expression}} expected-note {{to a consteval}}
512 { B b(nullptr, 0); }
513 { B b(&f_eval, 0); } // expected-error {{is not a constant expression}} expected-note {{to a consteval}}
514 { A a{}; }
515 { A a{&f_eval}; } // expected-error {{is not a constant expression}} expected-note {{to a consteval}}
516 { B b{nullptr, 0}; }
517 { B b{&f_eval, 0}; } // expected-error {{is not a constant expression}} expected-note {{to a consteval}}
518 { A a = A(); }
519 { A a = A(&f_eval); } // expected-error {{is not a constant expression}} expected-note {{to a consteval}}
520 { B b = B(nullptr, 0); }
521 { B b = B(&f_eval, 0); } // expected-error {{is not a constant expression}} expected-note {{to a consteval}}
522 { A a = A{}; }
523 { A a = A{&f_eval}; } // expected-error {{is not a constant expression}} expected-note {{to a consteval}}
524 { B b = B{nullptr, 0}; }
525 { B b = B{&f_eval, 0}; } // expected-error {{is not a constant expression}} expected-note {{to a consteval}}
526 { A a; a = A(); }
527 { A a; a = A(&f_eval); } // expected-error {{is not a constant expression}} expected-note {{to a consteval}}
528 { B b; b = B(nullptr, 0); }
529 { B b; b = B(&f_eval, 0); } // expected-error {{is not a constant expression}} expected-note {{to a consteval}}
530 { A a; a = A{}; }
531 { A a; a = A{&f_eval}; } // expected-error {{is not a constant expression}} expected-note {{to a consteval}}
532 { B b; b = B{nullptr, 0}; }
533 { B b; b = B{&f_eval, 0}; } // expected-error {{is not a constant expression}} expected-note {{to a consteval}}
534 { A* a; a = new A(); }
535 { A* a; a = new A(&f_eval); } // expected-error {{is not a constant expression}} expected-note {{to a consteval}}
536 { B* b; b = new B(nullptr, 0); }
537 { B* b; b = new B(&f_eval, 0); } // expected-error {{is not a constant expression}} expected-note {{to a consteval}}
538 { A* a; a = new A{}; }
539 { A* a; a = new A{&f_eval}; } // expected-error {{is not a constant expression}} expected-note {{to a consteval}}
540 { B* b; b = new B{nullptr, 0}; }
541 { B* b; b = new B{&f_eval, 0}; } // expected-error {{is not a constant expression}} expected-note {{to a consteval}}
542 }
543
544 }
545
546 namespace copy_ctor {
547
f_eval()548 consteval int f_eval() { // expected-note+ {{declared here}}
549 return 0;
550 }
551
552 struct Copy {
553 int(*ptr)();
Copycopy_ctor::Copy554 constexpr Copy(int(*p)() = nullptr) : ptr(p) {}
555 consteval Copy(const Copy&) = default;
556 };
557
to_lvalue_ref(const Copy && a)558 constexpr const Copy &to_lvalue_ref(const Copy &&a) {
559 return a;
560 }
561
test()562 void test() {
563 constexpr const Copy C;
564 // there is no the copy constructor call when its argument is a prvalue because of garanteed copy elision.
565 // so we need to test with both prvalue and xvalues.
566 { Copy c(C); }
567 { Copy c((Copy(&f_eval))); }// expected-error {{cannot take address of consteval}}
568 { Copy c(std::move(C)); }
569 { Copy c(std::move(Copy(&f_eval))); }// expected-error {{is not a constant expression}} expected-note {{to a consteval}}
570 { Copy c(to_lvalue_ref((Copy(&f_eval)))); }// expected-error {{is not a constant expression}} expected-note {{to a consteval}}
571 { Copy c(to_lvalue_ref(std::move(C))); }
572 { Copy c(to_lvalue_ref(std::move(Copy(&f_eval)))); }// expected-error {{is not a constant expression}} expected-note {{to a consteval}}
573 { Copy c = Copy(C); }
574 { Copy c = Copy(Copy(&f_eval)); }// expected-error {{cannot take address of consteval}}
575 { Copy c = Copy(std::move(C)); }
576 { Copy c = Copy(std::move(Copy(&f_eval))); }// expected-error {{is not a constant expression}} expected-note {{to a consteval}}
577 { Copy c = Copy(to_lvalue_ref(Copy(&f_eval))); }// expected-error {{is not a constant expression}} expected-note {{to a consteval}}
578 { Copy c = Copy(to_lvalue_ref(std::move(C))); }
579 { Copy c = Copy(to_lvalue_ref(std::move(Copy(&f_eval)))); }// expected-error {{is not a constant expression}} expected-note {{to a consteval}}
580 { Copy c; c = Copy(C); }
581 { Copy c; c = Copy(Copy(&f_eval)); }// expected-error {{cannot take address of consteval}}
582 { Copy c; c = Copy(std::move(C)); }
583 { Copy c; c = Copy(std::move(Copy(&f_eval))); }// expected-error {{is not a constant expression}} expected-note {{to a consteval}}
584 { Copy c; c = Copy(to_lvalue_ref(Copy(&f_eval))); }// expected-error {{is not a constant expression}} expected-note {{to a consteval}}
585 { Copy c; c = Copy(to_lvalue_ref(std::move(C))); }
586 { Copy c; c = Copy(to_lvalue_ref(std::move(Copy(&f_eval)))); }// expected-error {{is not a constant expression}} expected-note {{to a consteval}}
587 { Copy* c; c = new Copy(C); }
588 { Copy* c; c = new Copy(Copy(&f_eval)); }// expected-error {{cannot take address of consteval}}
589 { Copy* c; c = new Copy(std::move(C)); }
590 { Copy* c; c = new Copy(std::move(Copy(&f_eval))); }// expected-error {{is not a constant expression}} expected-note {{to a consteval}}
591 { Copy* c; c = new Copy(to_lvalue_ref(Copy(&f_eval))); }// expected-error {{is not a constant expression}} expected-note {{to a consteval}}
592 { Copy* c; c = new Copy(to_lvalue_ref(std::move(C))); }
593 { Copy* c; c = new Copy(to_lvalue_ref(std::move(Copy(&f_eval)))); }// expected-error {{is not a constant expression}} expected-note {{to a consteval}}
594 }
595
596 } // namespace special_ctor
597