xref: /llvm-project/clang/test/CodeGenCXX/cxx2b-static-call-operator.cpp (revision ee01a2c3996f9647f3158f5acdb921a6ede94dc1)
1ba15d186SMark de Wever // RUN: %clang_cc1 -std=c++23 %s -emit-llvm -triple x86_64-linux -o - | FileCheck %s
2ba15d186SMark de Wever // RUN: %clang_cc1 -std=c++23 %s -emit-llvm -triple x86_64-windows-msvc -o - | FileCheck %s
36523814cSRoy Jacobson 
46523814cSRoy Jacobson struct Functor {
operator ()Functor56523814cSRoy Jacobson   static int operator()(int x, int y) {
66523814cSRoy Jacobson     return x + y;
76523814cSRoy Jacobson   }
86523814cSRoy Jacobson };
96523814cSRoy Jacobson 
GetALambda()106523814cSRoy Jacobson auto GetALambda() {
116523814cSRoy Jacobson   return [](int x, int y) static {
126523814cSRoy Jacobson     return x + y;
136523814cSRoy Jacobson   };
146523814cSRoy Jacobson }
156523814cSRoy Jacobson 
CallsTheLambda()166523814cSRoy Jacobson void CallsTheLambda() {
176523814cSRoy Jacobson   GetALambda()(1, 2);
186523814cSRoy Jacobson }
196523814cSRoy Jacobson 
206523814cSRoy Jacobson // CHECK:      define {{.*}}CallsTheLambda{{.*}}
216523814cSRoy Jacobson // CHECK-NEXT: entry:
22*ee01a2c3STianlan Zhou // CHECK:        {{.*}}call {{.*}}GetALambda{{.*}}()
23*ee01a2c3STianlan Zhou // CHECK-NEXT:   {{.*}} = call noundef i32 {{.*}}(i32 noundef 1, i32 noundef 2)
246523814cSRoy Jacobson // CHECK-NEXT:   ret void
256523814cSRoy Jacobson // CHECK-NEXT: }
266523814cSRoy Jacobson 
GetAFunctor()27*ee01a2c3STianlan Zhou Functor GetAFunctor() {
28*ee01a2c3STianlan Zhou   return {};
29*ee01a2c3STianlan Zhou }
30*ee01a2c3STianlan Zhou 
call_static_call_operator()316523814cSRoy Jacobson void call_static_call_operator() {
326523814cSRoy Jacobson   Functor f;
336523814cSRoy Jacobson   f(101, 102);
346523814cSRoy Jacobson   f.operator()(201, 202);
356523814cSRoy Jacobson   Functor{}(301, 302);
363faf1f17SRoy Jacobson   Functor::operator()(401, 402);
37*ee01a2c3STianlan Zhou   GetAFunctor()(501, 502);
386523814cSRoy Jacobson }
396523814cSRoy Jacobson 
406523814cSRoy Jacobson // CHECK:      define {{.*}}call_static_call_operator{{.*}}
416523814cSRoy Jacobson // CHECK-NEXT: entry:
426523814cSRoy Jacobson // CHECK:        {{.*}} = call noundef i32 {{.*}}Functor{{.*}}(i32 noundef 101, i32 noundef 102)
436523814cSRoy Jacobson // CHECK-NEXT:   {{.*}} = call noundef i32 {{.*}}Functor{{.*}}(i32 noundef 201, i32 noundef 202)
446523814cSRoy Jacobson // CHECK-NEXT:   {{.*}} = call noundef i32 {{.*}}Functor{{.*}}(i32 noundef 301, i32 noundef 302)
453faf1f17SRoy Jacobson // CHECK-NEXT:   {{.*}} = call noundef i32 {{.*}}Functor{{.*}}(i32 noundef 401, i32 noundef 402)
46*ee01a2c3STianlan Zhou // CHECK:        {{.*}}call {{.*}}GetAFunctor{{.*}}()
47*ee01a2c3STianlan Zhou // CHECK-NEXT:   {{.*}} = call noundef i32 {{.*}}Functor{{.*}}(i32 noundef 501, i32 noundef 502)
486523814cSRoy Jacobson // CHECK-NEXT:   ret void
496523814cSRoy Jacobson // CHECK-NEXT: }
506523814cSRoy Jacobson 
516523814cSRoy Jacobson struct FunctorConsteval {
operator ()FunctorConsteval526523814cSRoy Jacobson   consteval static int operator()(int x, int y) {
536523814cSRoy Jacobson       return x + y;
546523814cSRoy Jacobson   }
556523814cSRoy Jacobson };
566523814cSRoy Jacobson 
576523814cSRoy Jacobson struct FunctorConstexpr {
operator ()FunctorConstexpr586523814cSRoy Jacobson   constexpr static int operator()(int x, int y) {
596523814cSRoy Jacobson       return x + y;
606523814cSRoy Jacobson   }
616523814cSRoy Jacobson };
626523814cSRoy Jacobson 
__anonc8d4a32b0202() 636523814cSRoy Jacobson constexpr auto my_lambda = []() constexpr {
646523814cSRoy Jacobson   return 3;
656523814cSRoy Jacobson };
666523814cSRoy Jacobson 
test_consteval_constexpr()676523814cSRoy Jacobson void test_consteval_constexpr() {
686523814cSRoy Jacobson   int x = 0;
696523814cSRoy Jacobson   int y = FunctorConstexpr{}(x, 2);
706523814cSRoy Jacobson   constexpr int z1 = FunctorConsteval{}(2, 2);
716523814cSRoy Jacobson   constexpr int z2 = FunctorConstexpr{}(2, 2);
726523814cSRoy Jacobson 
736523814cSRoy Jacobson   static_assert(z1 == 4);
746523814cSRoy Jacobson   static_assert(z2 == 4);
756523814cSRoy Jacobson 
766523814cSRoy Jacobson   constexpr auto my_lambda = []() constexpr static {
776523814cSRoy Jacobson       return 3;
786523814cSRoy Jacobson   };
796523814cSRoy Jacobson   constexpr int (*f)(void) = my_lambda;
806523814cSRoy Jacobson   constexpr int k = f();
816523814cSRoy Jacobson   static_assert(k == 3);
826523814cSRoy Jacobson }
836523814cSRoy Jacobson 
846523814cSRoy Jacobson template <class T>
856523814cSRoy Jacobson struct DepFunctor {
operator ()DepFunctor866523814cSRoy Jacobson   static int operator()(T t) {
876523814cSRoy Jacobson     return int(t);
886523814cSRoy Jacobson   }
896523814cSRoy Jacobson };
906523814cSRoy Jacobson 
916523814cSRoy Jacobson template<class T>
dep_lambda1()926523814cSRoy Jacobson auto dep_lambda1() {
936523814cSRoy Jacobson   return [](T t) static -> int {
946523814cSRoy Jacobson     return t;
956523814cSRoy Jacobson   };
966523814cSRoy Jacobson }
976523814cSRoy Jacobson 
dep_lambda2()986523814cSRoy Jacobson auto dep_lambda2() {
996523814cSRoy Jacobson   return [](auto t) static -> int {
1006523814cSRoy Jacobson     return t;
1016523814cSRoy Jacobson   };
1026523814cSRoy Jacobson }
1036523814cSRoy Jacobson 
test_dep_functors()1046523814cSRoy Jacobson void test_dep_functors() {
1056523814cSRoy Jacobson   int x = DepFunctor<float>{}(1.0f);
1066523814cSRoy Jacobson   int y = DepFunctor<bool>{}(true);
1076523814cSRoy Jacobson 
1086523814cSRoy Jacobson   int a = dep_lambda1<float>()(1.0f);
1096523814cSRoy Jacobson   int b = dep_lambda1<bool>()(true);
1106523814cSRoy Jacobson 
1116523814cSRoy Jacobson   int h = dep_lambda2()(1.0f);
1126523814cSRoy Jacobson   int i = dep_lambda2()(true);
1136523814cSRoy Jacobson }
1146523814cSRoy Jacobson 
1156523814cSRoy Jacobson // CHECK:      define {{.*}}test_dep_functors{{.*}}
1166523814cSRoy Jacobson // CHECK-NEXT: entry:
117*ee01a2c3STianlan Zhou // CHECK:        {{.*}} = call noundef i32 {{.*}}DepFunctor{{.*}}(float noundef 1.000000e+00)
118*ee01a2c3STianlan Zhou // CHECK:        {{.*}} = call noundef i32 {{.*}}DepFunctor{{.*}}(i1 noundef zeroext true)
119*ee01a2c3STianlan Zhou // CHECK:        {{.*}}call {{.*}}dep_lambda1{{.*}}()
120*ee01a2c3STianlan Zhou // CHECK:        {{.*}} = call noundef i32 {{.*}}dep_lambda1{{.*}}(float noundef 1.000000e+00)
121*ee01a2c3STianlan Zhou // CHECK:        {{.*}}call {{.*}}dep_lambda1{{.*}}()
122*ee01a2c3STianlan Zhou // CHECK:        {{.*}} = call noundef i32 {{.*}}dep_lambda1{{.*}}(i1 noundef zeroext true)
123*ee01a2c3STianlan Zhou // CHECK:        {{.*}}call {{.*}}dep_lambda2{{.*}}()
124*ee01a2c3STianlan Zhou // CHECK:        {{.*}} = call noundef i32 {{.*}}dep_lambda2{{.*}}(float noundef 1.000000e+00)
125*ee01a2c3STianlan Zhou // CHECK:        {{.*}}call {{.*}}dep_lambda2{{.*}}()
126*ee01a2c3STianlan Zhou // CHECK:        {{.*}} = call noundef i32 {{.*}}dep_lambda2{{.*}}(i1 noundef zeroext true)
1276523814cSRoy Jacobson // CHECK:        ret void
1286523814cSRoy Jacobson // CHECK-NEXT: }
1296523814cSRoy Jacobson 
1306523814cSRoy Jacobson 
1316523814cSRoy Jacobson struct __unique {
operator ()__unique1326523814cSRoy Jacobson     static constexpr auto operator()() { return 4; };
1336523814cSRoy Jacobson 
1346523814cSRoy Jacobson     using P = int();
operator P*__unique1356523814cSRoy Jacobson     constexpr operator P*() { return operator(); }
1366523814cSRoy Jacobson };
1376523814cSRoy Jacobson 
1386523814cSRoy Jacobson __unique four{};
1396523814cSRoy Jacobson 
test_four()1406523814cSRoy Jacobson int test_four() {
1416523814cSRoy Jacobson   // Checks that overload resolution works.
1426523814cSRoy Jacobson   return four();
1436523814cSRoy Jacobson }
144