1 // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -pedantic -verify=expected,both %s
2 // RUN: %clang_cc1 -std=c++14 -fexperimental-new-constant-interpreter -pedantic -verify=expected,both %s
3 // RUN: %clang_cc1 -std=c++20 -fexperimental-new-constant-interpreter -pedantic -verify=expected,both %s
4 // RUN: %clang_cc1 -pedantic -verify=ref,both %s
5 // RUN: %clang_cc1 -pedantic -std=c++14 -verify=ref,both %s
6 // RUN: %clang_cc1 -pedantic -std=c++20 -verify=ref,both %s
8 constexpr void doNothing() {}
9 constexpr int gimme5() {
13 static_assert(gimme5() == 5, "");
16 template<typename T
> constexpr T
identity(T t
) {
17 static_assert(true, "");
20 static_assert(identity(true), "");
21 static_assert(identity(true), ""); /// Compiled bytecode should be cached
22 static_assert(!identity(false), "");
24 template<typename A
, typename B
>
25 constexpr bool sameSize() {
26 static_assert(sizeof(A
) == sizeof(B
), ""); // both-error {{static assertion failed}} \
27 // both-note {{evaluates to}}
30 static_assert(sameSize
<int, int>(), "");
31 static_assert(sameSize
<unsigned int, int>(), "");
32 static_assert(sameSize
<char, long>(), ""); // both-note {{in instantiation of function template specialization}}
35 constexpr auto add(int a
, int b
) -> int {
36 return identity(a
) + identity(b
);
39 constexpr int sub(int a
, int b
) {
42 static_assert(sub(5, 2) == 3, "");
43 static_assert(sub(0, 5) == -5, "");
45 constexpr int norm(int n
) {
51 static_assert(norm(5) == norm(-5), "");
53 constexpr int square(int n
) {
54 return norm(n
) * norm(n
);
56 static_assert(square(2) == 4, "");
58 constexpr int add_second(int a
, int b
, bool doAdd
= true) {
63 static_assert(add_second(10, 3, true) == 13, "");
64 static_assert(add_second(10, 3) == 13, "");
65 static_assert(add_second(300, -20, false) == 300, "");
68 constexpr int sub(int a
, int b
, int c
) {
71 static_assert(sub(10, 8, 2) == 0, "");
74 constexpr int recursion(int i
) {
82 static_assert(recursion(10) == 0, "");
85 constexpr decltype(N
) getNum() {
88 static_assert(getNum
<-2>() == -2, "");
89 static_assert(getNum
<10>() == 10, "");
90 static_assert(getNum() == 5, "");
92 constexpr int f(); // both-note {{declared here}}
93 static_assert(f() == 5, ""); // both-error {{not an integral constant expression}} \
94 // both-note {{undefined function 'f'}}
101 static_assert(a() == 5, "");
103 constexpr int invalid() {
104 // Invalid expression in visit().
105 while(huh
) {} // both-error {{use of undeclared identifier}}
109 constexpr void invalid2() {
111 // Invalid expression in discard().
112 huh(); // both-error {{use of undeclared identifier}}
115 namespace FunctionPointers
{
116 constexpr int add(int a
, int b
) {
125 constexpr int applyBinOp(int a
, int b
, int (*op
)(int, int)) {
126 return op(a
, b
); // both-note {{evaluates to a null function pointer}}
128 static_assert(applyBinOp(1, 2, add
) == 3, "");
129 static_assert(applyBinOp(1, 2, nullptr) == 3, ""); // both-error {{not an integral constant expression}} \
130 // both-note {{in call to}}
133 constexpr int ignoreReturnValue() {
134 int (*foo
)(int, int) = add
;
139 static_assert(ignoreReturnValue() == 1, "");
141 constexpr int createS(S (*gimme
)()) {
142 gimme(); // Ignored return value
145 static_assert(createS(getS
) == 12, "");
147 namespace FunctionReturnType
{
148 typedef int (*ptr
)(int*);
151 constexpr int fun1(int* y
) {
154 constexpr ptr
fun() {
157 static_assert(fun() == nullptr, ""); // both-error {{static assertion failed}}
159 constexpr int foo() {
160 int (*f
)(int *) = fun();
167 static_assert(foo() == 10, "");
175 static_assert(s
.fp
== nullptr, ""); // zero-initialized function pointer.
177 constexpr int (*op
)(int, int) = add
;
178 constexpr bool b
= op
;
179 static_assert(op
, "");
180 static_assert(!!op
, "");
181 constexpr int (*op2
)(int, int) = nullptr;
182 static_assert(!op2
, "");
184 int m() { return 5;} // both-note {{declared here}}
185 constexpr int (*invalidFnPtr
)() = m
;
186 static_assert(invalidFnPtr() == 5, ""); // both-error {{not an integral constant expression}} \
187 // both-note {{non-constexpr function 'm'}}
191 void mismatched(int x
) {}
192 typedef void (*callback_t
)(int);
194 callback_t callback
= (callback_t
)mismatched
; // warns
195 /// Casts a function pointer to a boolean and then back to a function pointer.
196 /// This is extracted from test/Sema/callingconv-cast.c
197 callback
= (callback_t
)!mismatched
; // both-warning {{address of function 'mismatched' will always evaluate to 'true'}} \
198 // both-note {{prefix with the address-of operator to silence this warning}}
205 namespace Comparison
{
207 constexpr void (*pf
)() = &f
, (*pg
)() = &g
;
209 constexpr bool u13
= pf
< pg
; // both-warning {{ordered comparison of function pointers}} \
210 // both-error {{must be initialized by a constant expression}} \
211 // both-note {{comparison between '&f' and '&g' has unspecified value}}
213 constexpr bool u14
= pf
< (void(*)())nullptr; // both-warning {{ordered comparison of function pointers}} \
214 // both-error {{must be initialized by a constant expression}} \
215 // both-note {{comparison between '&f' and 'nullptr' has unspecified value}}
219 static_assert(pf
!= pg
, "");
220 static_assert(pf
== &f
, "");
221 static_assert(pg
== &g
, "");
224 constexpr int Double(int n
) { return 2 * n
; }
225 constexpr int Triple(int n
) { return 3 * n
; }
226 constexpr int Twice(int (*F
)(int), int n
) { return F(F(n
)); }
227 constexpr int Quadruple(int n
) { return Twice(Double
, n
); }
228 constexpr auto Select(int n
) -> int (*)(int) {
229 return n
== 2 ? &Double
: n
== 3 ? &Triple
: n
== 4 ? &Quadruple
: 0;
231 constexpr int Apply(int (*F
)(int), int n
) { return F(n
); } // both-note {{'F' evaluates to a null function pointer}}
233 constexpr int Invalid
= Apply(Select(0), 0); // both-error {{must be initialized by a constant expression}} \
234 // both-note {{in call to 'Apply(nullptr, 0)'}}
238 constexpr bool ok() const {
241 constexpr bool okRecurse() const {
246 struct BodylessMemberFunction
{
247 constexpr int first() const {
250 constexpr int second() const {
255 constexpr int nyd(int m
);
256 constexpr int doit() { return nyd(10); }
257 constexpr int nyd(int m
) { return m
; }
258 static_assert(doit() == 10, "");
260 namespace InvalidCall
{
262 constexpr int a() const { // both-error {{never produces a constant expression}}
263 return 1 / 0; // both-note 2{{division by zero}} \
264 // both-warning {{is undefined}}
268 static_assert(s
.a() == 1, ""); // both-error {{not an integral constant expression}} \
269 // both-note {{in call to}}
271 /// This used to cause an assertion failure in the new constant interpreter.
272 constexpr void func(); // both-note {{declared here}}
274 constexpr SS() { func(); } // both-note {{undefined function }}
276 constexpr SS ss
; // both-error {{must be initialized by a constant expression}} \
277 // both-note {{in call to 'SS()'}}
280 /// This should not emit a diagnostic.
288 static_assert(a() == 5, "");
292 namespace CallWithArgs
{
293 /// This used to call problems during checkPotentialConstantExpression() runs.
294 constexpr void g(int a
) {}
300 namespace ReturnLocalPtr
{
303 return &a
; // both-warning {{address of stack memory}}
306 /// GCC rejects the expression below, just like the new interpreter. The current interpreter
307 /// however accepts it and only warns about the function above returning an address to stack
308 /// memory. If we change the condition to 'p() != nullptr', it even succeeds.
309 static_assert(p() == nullptr, ""); // ref-error {{static assertion failed}} \
310 // expected-error {{not an integral constant expression}}
312 /// FIXME: The current interpreter emits diagnostics in the reference case below, but the
313 /// new one does not.
314 constexpr const int &p2() {
315 int a
= 12; // ref-note {{declared here}}
316 return a
; // both-warning {{reference to stack memory associated with local variable}}
319 static_assert(p2() == 12, ""); // both-error {{not an integral constant expression}} \
320 // ref-note {{read of variable whose lifetime has ended}}
323 namespace VoidReturn
{
324 /// ReturnStmt with an expression in a void function used to cause problems.
325 constexpr void bar() {}
326 constexpr void foo() {
329 static_assert((foo(),1) == 1, "");
332 namespace InvalidReclRefs
{
333 void param(bool b
) { // both-note {{declared here}}
334 static_assert(b
, ""); // both-error {{not an integral constant expression}} \
335 // both-note {{function parameter 'b' with unknown value}}
336 static_assert(true ? true : b
, "");
339 #if __cplusplus >= 202002L
340 consteval
void param2(bool b
) { // both-note {{declared here}}
341 static_assert(b
, ""); // both-error {{not an integral constant expression}} \
342 // both-note {{function parameter 'b' with unknown value}}
347 namespace TemplateUndefined
{
348 template<typename T
> constexpr int consume(T
);
349 // ok, not a constant expression.
350 const int k
= consume(0);
352 template<typename T
> constexpr int consume(T
) { return 0; }
353 // ok, constant expression.
354 constexpr int l
= consume(0);
355 static_assert(l
== 0, "");
358 namespace PtrReturn
{
359 constexpr void *a() {
362 static_assert(a() == nullptr, "");
366 struct S
{ int a
; bool b
; };
368 constexpr void variadic_function(int a
, ...) {}
370 variadic_function(1, S
{'a', false});
373 static_assert(f1() == 1, "");
375 constexpr int variadic_function2(...) {
378 static_assert(variadic_function2() == 12, "");
379 static_assert(variadic_function2(1, 2, 3, 4, 5) == 12, "");
380 static_assert(variadic_function2(1, variadic_function2()) == 12, "");
382 constexpr int (*VFP
)(...) = variadic_function2
;
383 static_assert(VFP() == 12, "");
388 constexpr void bla(...) {}
389 constexpr S
bla2(...) {
392 constexpr Foo(...) : a(1337) {}
393 constexpr Foo(void *c
, bool b
, void*p
, ...) : a('a' + b
) {}
394 constexpr Foo(int a
, const S
* s
, ...) : a(a
) {}
397 constexpr int foo2() {
399 auto s
= f
.bla2(1, 2, S
{1, false});
402 static_assert(foo2() == 13, "");
404 constexpr Foo _f
= 123;
405 static_assert(_f
.a
== 1337, "");
407 constexpr Foo
__f(nullptr, false, nullptr, nullptr, 'a', Foo());
408 static_assert(__f
.a
== 'a', "");
411 #if __cplusplus >= 202002L
412 namespace VariadicVirtual
{
415 constexpr virtual void foo(int &a
, ...) {
422 constexpr void foo(int &a
, ...) override
{
427 constexpr int foo() {
430 b
.foo(a
, 1,2,nullptr);
433 static_assert(foo() == 2, "");
436 namespace VariadicQualified
{
439 constexpr virtual int foo(...) const {
443 class B
: public A
{};
446 constexpr int foo(...) const override
{
447 return B::foo(1,2,3); // B doesn't have a foo(), so this should call A::foo().
449 constexpr int foo2() const {
450 return this->A::foo(1,2,3,this);
454 static_assert(c
.foo() == 5);
455 static_assert(c
.foo2() == 5);
456 } // VariadicQualified
462 template<typename
...T
>
463 constexpr int foo() { return sizeof...(T
); }
464 static_assert(foo
<int, char>() == 2, "");
465 static_assert(foo
<>() == 0, "");
468 namespace AddressOf
{
470 static_assert(__builtin_addressof(s
) == &s
, "");
472 struct T
{ constexpr T
*operator&() const { return nullptr; } int n
; } t
;
473 constexpr T
*pt
= __builtin_addressof(t
);
474 static_assert(&pt
->n
== &t
.n
, "");
476 struct U
{ int n
: 5; } u
;
477 int *pbf
= __builtin_addressof(u
.n
); // both-error {{address of bit-field requested}}
479 S
*ptmp
= __builtin_addressof(S
{}); // both-error {{taking the address of a temporary}} \
480 // both-warning {{temporary whose address is used as value of local variable 'ptmp' will be destroyed at the end of the full-expression}}
482 constexpr int foo() {return 1;}
483 static_assert(__builtin_addressof(foo
) == foo
, "");
485 constexpr _Complex
float F
= {3, 4}; // both-warning {{'_Complex' is a C99 extension}}
486 static_assert(__builtin_addressof(F
) == &F
, "");
488 void testAddressof(int x
) {
489 static_assert(&x
== __builtin_addressof(x
), "");
494 template <typename T
> struct remove_reference
{ using type
= T
; };
495 template <typename T
> struct remove_reference
<T
&> { using type
= T
; };
496 template <typename T
> struct remove_reference
<T
&&> { using type
= T
; };
497 template <typename T
>
498 constexpr typename
std::remove_reference
<T
>::type
&& move(T
&&t
) noexcept
{
499 return static_cast<typename
std::remove_reference
<T
>::type
&&>(t
);
502 /// The std::move declaration above gets translated to a builtin function.
504 #if __cplusplus >= 202002L
505 consteval
int f_eval() { // both-note 12{{declared here}}
509 /// From test/SemaCXX/cxx2a-consteval.
512 constexpr Copy(int(*p
)() = nullptr) : ptr(p
) {}
513 consteval
Copy(const Copy
&) = default;
516 constexpr const Copy
&to_lvalue_ref(const Copy
&&a
) {
521 constexpr const Copy C
;
522 // there is no the copy constructor call when its argument is a prvalue because of garanteed copy elision.
523 // so we need to test with both prvalue and xvalues.
525 { Copy
c((Copy(&f_eval
))); } // both-error {{cannot take address of consteval}}
526 { Copy
c(std::move(C
)); }
527 { Copy
c(std::move(Copy(&f_eval
))); } // both-error {{is not a constant expression}} \
528 // both-note {{to a consteval}}
529 { Copy
c(to_lvalue_ref((Copy(&f_eval
)))); } // both-error {{is not a constant expression}} \
530 // both-note {{to a consteval}}
531 { Copy
c(to_lvalue_ref(std::move(C
))); }
532 { Copy
c(to_lvalue_ref(std::move(Copy(&f_eval
)))); } // both-error {{is not a constant expression}} \
533 // both-note {{to a consteval}}
534 { Copy c
= Copy(C
); }
535 { Copy c
= Copy(Copy(&f_eval
)); } // both-error {{cannot take address of consteval}}
536 { Copy c
= Copy(std::move(C
)); }
537 { Copy c
= Copy(std::move(Copy(&f_eval
))); } // both-error {{is not a constant expression}} \
538 // both-note {{to a consteval}}
539 { Copy c
= Copy(to_lvalue_ref(Copy(&f_eval
))); } // both-error {{is not a constant expression}} \
540 // both-note {{to a consteval}}
541 { Copy c
= Copy(to_lvalue_ref(std::move(C
))); }
542 { Copy c
= Copy(to_lvalue_ref(std::move(Copy(&f_eval
)))); } // both-error {{is not a constant expression}} \
543 // both-note {{to a consteval}}
544 { Copy c
; c
= Copy(C
); }
545 { Copy c
; c
= Copy(Copy(&f_eval
)); } // both-error {{cannot take address of consteval}}
546 { Copy c
; c
= Copy(std::move(C
)); }
547 { Copy c
; c
= Copy(std::move(Copy(&f_eval
))); } // both-error {{is not a constant expression}} \
548 // both-note {{to a consteval}}
549 { Copy c
; c
= Copy(to_lvalue_ref(Copy(&f_eval
))); } // both-error {{is not a constant expression}} \
550 // both-note {{to a consteval}}
551 { Copy c
; c
= Copy(to_lvalue_ref(std::move(C
))); }
552 { Copy c
; c
= Copy(to_lvalue_ref(std::move(Copy(&f_eval
)))); } // both-error {{is not a constant expression}} \
553 // both-note {{to a consteval}}
556 constexpr int A
= std::move(5);
557 static_assert(A
== 5, "");
560 namespace StaticLocals
{
562 static int j
; // both-note {{declared here}}
563 static_assert(&j
!= nullptr, ""); // both-warning {{always true}}
565 static_assert(j
== 0, ""); // both-error {{not an integral constant expression}} \
566 // both-note {{read of non-const variable 'j'}}
568 static int k
= 0; // both-note {{declared here}}
569 static_assert(k
== 0, ""); // both-error {{not an integral constant expression}} \
570 // both-note {{read of non-const variable 'k'}}
572 static const int l
= 12;
573 static_assert(l
== 12, "");
575 static const int m
; // both-error {{default initialization}}
576 static_assert(m
== 0, "");
581 /// We used to run into infinite recursin here because we were
582 /// trying to evaluate t's initializer while evaluating t's initializer.
589 namespace VariadicOperator
{
591 float& operator()(...);
594 void test_callable(Callable c
) {
599 namespace WeakCompare
{
600 [[gnu::weak
]]void weak_method();
601 static_assert(weak_method
!= nullptr, ""); // both-error {{not an integral constant expression}} \
602 // both-note {{comparison against address of weak declaration '&weak_method' can only be performed at runtim}}
604 constexpr auto A
= &weak_method
;
605 static_assert(A
!= nullptr, ""); // both-error {{not an integral constant expression}} \
606 // both-note {{comparison against address of weak declaration '&weak_method' can only be performed at runtim}}
609 namespace FromIntegral
{
610 #if __cplusplus >= 202002L
611 typedef double (*DoubleFn
)();
612 int a
[(int)DoubleFn((void*)-1)()]; // both-error {{not allowed at file scope}} \
613 // both-warning {{variable length arrays}}
614 int b
[(int)DoubleFn((void*)(-1 + 1))()]; // both-error {{not allowed at file scope}} \
615 // expected-note {{evaluates to a null function pointer}} \
616 // both-warning {{variable length arrays}}
621 template <typename T
> using id
= T
;
622 template <typename T
>
624 constexpr id
<void (T
)> f
;
627 static_assert((g
<int>(), true), "");
631 /// The InitListExpr here is of void type.
632 void bir
[[clang::annotate("B", {1, 2, 3, 4})]] (); // both-error {{'annotate' attribute requires parameter 1 to be a constant expression}} \
633 // both-note {{subexpression not valid in a constant expression}}
636 namespace FuncPtrParam
{
637 void foo(int(&a
)()) {
638 *a
; // both-warning {{expression result unused}}
648 namespace FunctionCast
{
649 // When folding, we allow functions to be cast to different types. Such
650 // cast functions cannot be called, even if they're constexpr.
651 constexpr int f() { return 1; }
652 typedef double (*DoubleFn
)();
653 typedef int (*IntFn
)();
654 int a
[(int)DoubleFn(f
)()]; // both-error {{variable length array}} \
655 // both-warning {{are a Clang extension}}
656 int b
[(int)IntFn(f
)()]; // ok
659 #if __cplusplus >= 202002L
660 namespace StableAddress
{
661 template<unsigned N
> struct str
{
664 // FIXME: Deduction guide not needed with P1816R0.
665 template<unsigned N
> str(const char (&)[N
]) -> str
<N
>;
667 template<str s
> constexpr int sum() {
673 static_assert(sum
<str
{"$hello $world."}>() == 1234, "");