[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / SemaTemplate / concepts-using-decl.cpp
blobfca69dea5c88f5c7bfc5bcfcb7010a66dadae0d4
1 // RUN: %clang_cc1 -std=c++20 -verify %s
3 namespace static_methods {
4 template<class> concept False = false;
6 struct Base {
7 static void foo(auto);
8 };
9 struct Derived : public Base {
10 using Base::foo;
11 static void foo(False auto);
13 void func() {
14 Derived::foo(42);
16 } // namespace static_methods
18 namespace constrained_members {
19 template <unsigned n> struct Opaque {};
20 template <unsigned n> void expect(Opaque<n> _) {}
22 struct Empty{};
23 constexpr int EmptySize = sizeof(Empty);
25 template<typename T> concept IsEmpty = sizeof(T) == EmptySize;
27 namespace base_members_not_hidden {
28 struct base {
29 template <typename T>
30 Opaque<0> foo() { return Opaque<0>(); };
33 struct bar1 : public base {
34 using base::foo;
35 template <typename T> requires IsEmpty<T>
36 Opaque<1> foo() { return Opaque<1>(); };
39 struct bar2 : public base {
40 using base::foo;
41 template <IsEmpty T>
42 Opaque<1> foo() { return Opaque<1>(); };
45 struct bar3 : public base {
46 using base::foo;
47 template <typename T>
48 Opaque<1> foo() requires IsEmpty<T> { return Opaque<1>(); };
51 void func() {
52 expect<0>(base{}.foo<Empty>());
53 expect<0>(base{}.foo<int>());
54 expect<1>(bar1{}.foo<Empty>());
55 expect<0>(bar1{}.foo<int>());
56 expect<1>(bar2{}.foo<Empty>());
57 expect<0>(bar2{}.foo<int>());
58 expect<1>(bar3{}.foo<Empty>());
59 expect<0>(bar3{}.foo<int>());
62 namespace base_members_hidden {
63 struct base1 {
64 template <typename T> requires IsEmpty<T>
65 Opaque<0> foo() { return Opaque<0>(); }; // expected-note {{candidate function}}
67 struct bar1 : public base1 {
68 using base1::foo;
69 template <typename T> requires IsEmpty<T>
70 Opaque<1> foo() { return Opaque<1>(); };
72 struct base2 {
73 template <IsEmpty T>
74 Opaque<0> foo() { return Opaque<0>(); };
76 struct bar2 : public base2 {
77 using base2::foo;
78 template <IsEmpty T>
79 Opaque<1> foo() { return Opaque<1>(); };
81 struct baz : public base1 {
82 using base1::foo;
83 template <typename T> requires IsEmpty<T> && IsEmpty<T>
84 Opaque<1> foo() { return Opaque<1>(); }; // expected-note {{candidate function}}
86 void func() {
87 expect<0>(base1{}.foo<Empty>());
88 expect<1>(bar1{}.foo<Empty>());
89 expect<0>(base2{}.foo<Empty>());
90 expect<1>(bar2{}.foo<Empty>());
91 baz{}.foo<Empty>(); // expected-error {{call to member function 'foo' is ambiguous}}
93 } // namespace base_members_hidden
95 namespace same_contraint_at_different_place {
96 struct base {
97 template <IsEmpty T>
98 void foo1() {}; // expected-note 2 {{candidate function}}
99 template <typename T> requires IsEmpty<T>
100 void foo2() {}; // expected-note 2 {{candidate function}}
101 template <typename T>
102 void foo3() requires IsEmpty<T> {}; // expected-note 2 {{candidate function}}
104 struct bar1 : public base {
105 using base::foo1;
106 using base::foo2;
107 using base::foo3;
108 template <typename T> requires IsEmpty<T>
109 void foo1() {}; // expected-note {{candidate function}}
110 template <IsEmpty T>
111 void foo2() {}; // expected-note {{candidate function}}
112 template <IsEmpty T>
113 void foo3() {}; // expected-note {{candidate function}}
115 struct bar2 : public base {
116 using base::foo1;
117 using base::foo2;
118 using base::foo3;
119 template <typename T>
120 void foo1() requires IsEmpty<T> {}; // expected-note {{candidate function}}
121 template <typename T>
122 void foo2() requires IsEmpty<T> {}; // expected-note {{candidate function}}
123 template <typename T> requires IsEmpty<T>
124 void foo3() {}; // expected-note {{candidate function}}
126 void func() {
127 bar1{}.foo1<Empty>(); // expected-error {{call to member function 'foo1' is ambiguous}}
128 bar1{}.foo2<Empty>(); // expected-error {{call to member function 'foo2' is ambiguous}}
129 bar1{}.foo3<Empty>(); // expected-error {{call to member function 'foo3' is ambiguous}}
130 bar2{}.foo1<Empty>(); // expected-error {{call to member function 'foo1' is ambiguous}}
131 bar2{}.foo2<Empty>(); // expected-error {{call to member function 'foo2' is ambiguous}}
132 bar2{}.foo3<Empty>(); // expected-error {{call to member function 'foo3' is ambiguous}}
134 } // namespace same_constraint_at_different_place
136 namespace more_constrained {
137 struct base1 {
138 template <class T> Opaque<0> foo() { return Opaque<0>(); }
140 struct derived1 : base1 {
141 using base1::foo;
142 template <IsEmpty T> Opaque<1> foo() { return Opaque<1>(); }
144 struct base2 {
145 template <IsEmpty T> Opaque<0> foo() { return Opaque<0>(); }
147 struct derived2 : base2 {
148 using base2::foo;
149 template <class T> Opaque<1> foo() { return Opaque<1>(); }
151 void func() {
152 expect<0>(derived1{}.foo<int>());
153 expect<1>(derived1{}.foo<Empty>());
154 expect<0>(derived2{}.foo<Empty>());
155 expect<1>(derived2{}.foo<int>());
157 } // namespace more_constrained
158 } // namespace constrained_members
160 namespace heads_without_concepts {
161 struct base {
162 template <int N, int M>
163 int foo() { return 1; };
166 struct bar : public base {
167 using base::foo;
168 template <int N>
169 int foo() { return 2; }; // expected-note {{candidate template ignored: substitution failure: too many template arguments for function template 'foo'}}
172 void func() {
173 bar f;
174 f.foo<10>();
175 // FIXME(GH58571): bar::foo should not hide base::foo.
176 f.foo<10, 10>(); // expected-error {{no matching member function for call to 'foo'}}
178 } // namespace heads_without_concepts.