File: cxx2b-static-call-operator.cpp

package info (click to toggle)
llvm-toolchain-17 1%3A17.0.6-22
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,799,624 kB
  • sloc: cpp: 6,428,607; ansic: 1,383,196; asm: 793,408; python: 223,504; objc: 75,364; f90: 60,502; lisp: 33,869; pascal: 15,282; sh: 9,684; perl: 7,453; ml: 4,937; awk: 3,523; makefile: 2,889; javascript: 2,149; xml: 888; fortran: 619; cs: 573
file content (131 lines) | stat: -rw-r--r-- 3,352 bytes parent folder | download | duplicates (2)
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();
}