1 // RUN: %clang_cc1 -std=c++20 -verify %s
3 namespace static_methods
{
4 template<class> concept False
= false;
9 struct Derived
: public Base
{
11 static void foo(False
auto);
16 } // namespace static_methods
18 namespace constrained_members
{
19 template <unsigned n
> struct Opaque
{};
20 template <unsigned n
> void expect(Opaque
<n
> _
) {}
23 constexpr int EmptySize
= sizeof(Empty
);
25 template<typename T
> concept IsEmpty
= sizeof(T
) == EmptySize
;
27 namespace base_members_not_hidden
{
30 Opaque
<0> foo() { return Opaque
<0>(); };
33 struct bar1
: public base
{
35 template <typename T
> requires IsEmpty
<T
>
36 Opaque
<1> foo() { return Opaque
<1>(); };
39 struct bar2
: public base
{
42 Opaque
<1> foo() { return Opaque
<1>(); };
45 struct bar3
: public base
{
48 Opaque
<1> foo() requires IsEmpty
<T
> { return Opaque
<1>(); };
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
{
64 template <typename T
> requires IsEmpty
<T
>
65 Opaque
<0> foo() { return Opaque
<0>(); }; // expected-note {{candidate function}}
67 struct bar1
: public base1
{
69 template <typename T
> requires IsEmpty
<T
>
70 Opaque
<1> foo() { return Opaque
<1>(); };
74 Opaque
<0> foo() { return Opaque
<0>(); };
76 struct bar2
: public base2
{
79 Opaque
<1> foo() { return Opaque
<1>(); };
81 struct baz
: public base1
{
83 template <typename T
> requires IsEmpty
<T
> && IsEmpty
<T
>
84 Opaque
<1> foo() { return Opaque
<1>(); }; // expected-note {{candidate function}}
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
{
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
{
108 template <typename T
> requires IsEmpty
<T
>
109 void foo1() {}; // expected-note {{candidate function}}
111 void foo2() {}; // expected-note {{candidate function}}
113 void foo3() {}; // expected-note {{candidate function}}
115 struct bar2
: public base
{
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}}
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
{
138 template <class T
> Opaque
<0> foo() { return Opaque
<0>(); }
140 struct derived1
: base1
{
142 template <IsEmpty T
> Opaque
<1> foo() { return Opaque
<1>(); }
145 template <IsEmpty T
> Opaque
<0> foo() { return Opaque
<0>(); }
147 struct derived2
: base2
{
149 template <class T
> Opaque
<1> foo() { return Opaque
<1>(); }
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
{
162 template <int N
, int M
>
163 int foo() { return 1; };
166 struct bar
: public base
{
169 int foo() { return 2; }; // expected-note {{candidate template ignored: substitution failure: too many template arguments for function template 'foo'}}
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.