• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
__anonf0217b440102(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 
__anonf0217b440202(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 {{function parameter}}
242   return f(0);
243 }
244 
f_eval(int i)245 consteval int f_eval(int i) {
246   return f(i);
247 }
248 
__anonf0217b440302(int i) 249 auto l0 = [](int i) consteval {
250   return f(i);
251 };
252 
__anonf0217b440402(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 {{function parameter}}
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