1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
// RUN: %clang_cc1 -std=c++23 %s -emit-llvm -triple x86_64-linux -o - | FileCheck %s
// RUN: %clang_cc1 -std=c++23 %s -emit-llvm -triple x86_64-windows-msvc -o - | FileCheck %s
struct Functor {
static int operator()(int x, int y) {
return x + y;
}
};
auto GetALambda() {
return [](int x, int y) static {
return x + y;
};
}
void CallsTheLambda() {
GetALambda()(1, 2);
}
// CHECK: define {{.*}}CallsTheLambda{{.*}}
// CHECK-NEXT: entry:
// CHECK-NEXT: %call = call noundef i32 {{.*}}(i32 noundef 1, i32 noundef 2)
// CHECK-NEXT: ret void
// CHECK-NEXT: }
void call_static_call_operator() {
Functor f;
f(101, 102);
f.operator()(201, 202);
Functor{}(301, 302);
Functor::operator()(401, 402);
}
// CHECK: define {{.*}}call_static_call_operator{{.*}}
// CHECK-NEXT: entry:
// CHECK: {{.*}} = call noundef i32 {{.*}}Functor{{.*}}(i32 noundef 101, i32 noundef 102)
// CHECK-NEXT: {{.*}} = call noundef i32 {{.*}}Functor{{.*}}(i32 noundef 201, i32 noundef 202)
// CHECK-NEXT: {{.*}} = call noundef i32 {{.*}}Functor{{.*}}(i32 noundef 301, i32 noundef 302)
// CHECK-NEXT: {{.*}} = call noundef i32 {{.*}}Functor{{.*}}(i32 noundef 401, i32 noundef 402)
// CHECK-NEXT: ret void
// CHECK-NEXT: }
struct FunctorConsteval {
consteval static int operator()(int x, int y) {
return x + y;
}
};
struct FunctorConstexpr {
constexpr static int operator()(int x, int y) {
return x + y;
}
};
constexpr auto my_lambda = []() constexpr {
return 3;
};
void test_consteval_constexpr() {
int x = 0;
int y = FunctorConstexpr{}(x, 2);
constexpr int z1 = FunctorConsteval{}(2, 2);
constexpr int z2 = FunctorConstexpr{}(2, 2);
static_assert(z1 == 4);
static_assert(z2 == 4);
constexpr auto my_lambda = []() constexpr static {
return 3;
};
constexpr int (*f)(void) = my_lambda;
constexpr int k = f();
static_assert(k == 3);
}
template <class T>
struct DepFunctor {
static int operator()(T t) {
return int(t);
}
};
template<class T>
auto dep_lambda1() {
return [](T t) static -> int {
return t;
};
}
auto dep_lambda2() {
return [](auto t) static -> int {
return t;
};
}
void test_dep_functors() {
int x = DepFunctor<float>{}(1.0f);
int y = DepFunctor<bool>{}(true);
int a = dep_lambda1<float>()(1.0f);
int b = dep_lambda1<bool>()(true);
int h = dep_lambda2()(1.0f);
int i = dep_lambda2()(true);
}
// CHECK: define {{.*}}test_dep_functors{{.*}}
// CHECK-NEXT: entry:
// CHECK: %call = call noundef i32 {{.*}}DepFunctor{{.*}}(float noundef 1.000000e+00)
// CHECK: %call1 = call noundef i32 {{.*}}DepFunctor{{.*}}(i1 noundef zeroext true)
// CHECK: %call2 = call noundef i32 {{.*}}dep_lambda1{{.*}}(float noundef 1.000000e+00)
// CHECK: %call3 = call noundef i32 {{.*}}dep_lambda1{{.*}}(i1 noundef zeroext true)
// CHECK: %call4 = call noundef i32 {{.*}}dep_lambda2{{.*}}(float noundef 1.000000e+00)
// CHECK: %call5 = call noundef i32 {{.*}}dep_lambda2{{.*}}(i1 noundef zeroext true)
// CHECK: ret void
// CHECK-NEXT: }
struct __unique {
static constexpr auto operator()() { return 4; };
using P = int();
constexpr operator P*() { return operator(); }
};
__unique four{};
int test_four() {
// Checks that overload resolution works.
return four();
}
|