[flang][cuda] Adapt ExternalNameConversion to work in gpu module (#117039)
[llvm-project.git] / clang / test / AST / ByteCode / functions.cpp
blobb00f59a8d8d433da289fdc7642a5443625c5c839
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() {
10 doNothing();
11 return 5;
13 static_assert(gimme5() == 5, "");
16 template<typename T> constexpr T identity(T t) {
17 static_assert(true, "");
18 return t;
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}}
28 return true;
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) {
40 return a - b;
42 static_assert(sub(5, 2) == 3, "");
43 static_assert(sub(0, 5) == -5, "");
45 constexpr int norm(int n) {
46 if (n >= 0) {
47 return identity(n);
49 return -identity(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) {
59 if (doAdd)
60 return a + b;
61 return a;
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) {
69 return a - b - c;
71 static_assert(sub(10, 8, 2) == 0, "");
74 constexpr int recursion(int i) {
75 doNothing();
76 i = i - 1;
77 if (i == 0)
78 return identity(0);
80 return recursion(i);
82 static_assert(recursion(10) == 0, "");
84 template<int N = 5>
85 constexpr decltype(N) getNum() {
86 return N;
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'}}
95 constexpr int a() {
96 return f();
98 constexpr int f() {
99 return 5;
101 static_assert(a() == 5, "");
103 constexpr int invalid() {
104 // Invalid expression in visit().
105 while(huh) {} // both-error {{use of undeclared identifier}}
106 return 0;
109 constexpr void invalid2() {
110 int i = 0;
111 // Invalid expression in discard().
112 huh(); // both-error {{use of undeclared identifier}}
115 namespace FunctionPointers {
116 constexpr int add(int a, int b) {
117 return a + b;
120 struct S { int a; };
121 constexpr S getS() {
122 return S{12};
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;
136 foo(1, 2);
137 return 1;
139 static_assert(ignoreReturnValue() == 1, "");
141 constexpr int createS(S (*gimme)()) {
142 gimme(); // Ignored return value
143 return gimme().a;
145 static_assert(createS(getS) == 12, "");
147 namespace FunctionReturnType {
148 typedef int (*ptr)(int*);
149 typedef ptr (*pm)();
151 constexpr int fun1(int* y) {
152 return *y + 10;
154 constexpr ptr fun() {
155 return &fun1;
157 static_assert(fun() == nullptr, ""); // both-error {{static assertion failed}}
159 constexpr int foo() {
160 int (*f)(int *) = fun();
161 int m = 0;
163 m = f(&m);
165 return m;
167 static_assert(foo() == 10, "");
169 struct S {
170 int i;
171 void (*fp)();
174 constexpr S s{ 12 };
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'}}
190 namespace ToBool {
191 void mismatched(int x) {}
192 typedef void (*callback_t)(int);
193 void foo() {
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 {
206 void f(), g();
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)'}}
237 struct F {
238 constexpr bool ok() const {
239 return okRecurse();
241 constexpr bool okRecurse() const {
242 return true;
246 struct BodylessMemberFunction {
247 constexpr int first() const {
248 return second();
250 constexpr int second() const {
251 return 1;
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 {
261 struct S {
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}}
267 constexpr S s;
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}}
273 struct SS {
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.
281 constexpr int f();
282 constexpr int a() {
283 return f();
285 constexpr int f() {
286 return 5;
288 static_assert(a() == 5, "");
292 namespace CallWithArgs {
293 /// This used to call problems during checkPotentialConstantExpression() runs.
294 constexpr void g(int a) {}
295 constexpr void f() {
296 g(0);
300 namespace ReturnLocalPtr {
301 constexpr int *p() {
302 int a = 12;
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() {
327 return bar();
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}}
344 #endif
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() {
360 return nullptr;
362 static_assert(a() == nullptr, "");
365 namespace Variadic {
366 struct S { int a; bool b; };
368 constexpr void variadic_function(int a, ...) {}
369 constexpr int f1() {
370 variadic_function(1, S{'a', false});
371 return 1;
373 static_assert(f1() == 1, "");
375 constexpr int variadic_function2(...) {
376 return 12;
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, "");
385 /// Member functions
386 struct Foo {
387 int a = 0;
388 constexpr void bla(...) {}
389 constexpr S bla2(...) {
390 return S{12, true};
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() {
398 Foo f(1, nullptr);
399 auto s = f.bla2(1, 2, S{1, false});
400 return s.a + s.b;
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 {
413 class A {
414 public:
415 constexpr virtual void foo(int &a, ...) {
416 a = 1;
420 class B : public A {
421 public:
422 constexpr void foo(int &a, ...) override {
423 a = 2;
427 constexpr int foo() {
428 B b;
429 int a;
430 b.foo(a, 1,2,nullptr);
431 return a;
433 static_assert(foo() == 2, "");
434 } // VariadicVirtual
436 namespace VariadicQualified {
437 class A {
438 public:
439 constexpr virtual int foo(...) const {
440 return 5;
443 class B : public A {};
444 class C : public B {
445 public:
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);
453 constexpr C c;
454 static_assert(c.foo() == 5);
455 static_assert(c.foo2() == 5);
456 } // VariadicQualified
457 #endif
461 namespace Packs {
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 {
469 struct S {} s;
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), "");
493 namespace std {
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.
503 namespace Move {
504 #if __cplusplus >= 202002L
505 consteval int f_eval() { // both-note 12{{declared here}}
506 return 0;
509 /// From test/SemaCXX/cxx2a-consteval.
510 struct Copy {
511 int(*ptr)();
512 constexpr Copy(int(*p)() = nullptr) : ptr(p) {}
513 consteval Copy(const Copy&) = default;
516 constexpr const Copy &to_lvalue_ref(const Copy &&a) {
517 return a;
520 void test() {
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.
524 { Copy c(C); }
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}}
555 #endif
556 constexpr int A = std::move(5);
557 static_assert(A == 5, "");
560 namespace StaticLocals {
561 void test() {
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, "");
580 namespace Local {
581 /// We used to run into infinite recursin here because we were
582 /// trying to evaluate t's initializer while evaluating t's initializer.
583 int a() {
584 const int t=t;
585 return t;
589 namespace VariadicOperator {
590 struct Callable {
591 float& operator()(...);
594 void test_callable(Callable c) {
595 float &fr = c(10);
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}}
617 #endif
620 namespace {
621 template <typename T> using id = T;
622 template <typename T>
623 constexpr void g() {
624 constexpr id<void (T)> f;
627 static_assert((g<int>(), true), "");
630 namespace {
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}}
642 namespace {
643 void f() noexcept;
644 void (&r)() = f;
645 void (&cond3)() = r;
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 {
662 char arr[N];
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() {
668 int n = 0;
669 for (char c : s.arr)
670 n += c;
671 return n;
673 static_assert(sum<str{"$hello $world."}>() == 1234, "");
675 #endif