200 lines · cpp
1// RUN: %clang_cc1 -std=c++20 -verify %s2 3namespace static_methods {4template<class> concept False = false;5 6struct Base {7 static void foo(auto);8};9struct Derived : public Base {10 using Base::foo;11 static void foo(False auto);12};13void func() {14 Derived::foo(42);15}16} // namespace static_methods17 18namespace constrained_members {19template <unsigned n> struct Opaque {};20template <unsigned n> void expect(Opaque<n> _) {}21 22struct Empty{};23constexpr int EmptySize = sizeof(Empty);24 25template<typename T> concept IsEmpty = sizeof(T) == EmptySize;26 27namespace base_members_not_hidden {28struct base {29 template <typename T>30 Opaque<0> foo() { return Opaque<0>(); };31};32 33struct bar1 : public base {34 using base::foo;35 template <typename T> requires IsEmpty<T> 36 Opaque<1> foo() { return Opaque<1>(); };37};38 39struct bar2 : public base {40 using base::foo;41 template <IsEmpty T>42 Opaque<1> foo() { return Opaque<1>(); };43};44 45struct bar3 : public base {46 using base::foo;47 template <typename T>48 Opaque<1> foo() requires IsEmpty<T> { return Opaque<1>(); };49};50 51void 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>());60}61}62namespace base_members_hidden {63struct base1 {64 template <typename T> requires IsEmpty<T>65 Opaque<0> foo() { return Opaque<0>(); }; // expected-note {{candidate function}}66};67struct bar1 : public base1 {68 using base1::foo;69 template <typename T> requires IsEmpty<T>70 Opaque<1> foo() { return Opaque<1>(); };71};72struct base2 {73 template <IsEmpty T>74 Opaque<0> foo() { return Opaque<0>(); };75};76struct bar2 : public base2 {77 using base2::foo;78 template <IsEmpty T>79 Opaque<1> foo() { return Opaque<1>(); };80};81struct 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}}85};86void 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}}92}93} // namespace base_members_hidden94 95namespace same_contraint_at_different_place {96struct 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}}103};104struct 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}}114};115struct 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}}125};126void 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}}133}134} // namespace same_constraint_at_different_place135 136namespace more_constrained {137struct base1 { 138 template <class T> Opaque<0> foo() { return Opaque<0>(); }139};140struct derived1 : base1 { 141 using base1::foo;142 template <IsEmpty T> Opaque<1> foo() { return Opaque<1>(); }143};144struct base2 { 145 template <IsEmpty T> Opaque<0> foo() { return Opaque<0>(); }146};147struct derived2 : base2 { 148 using base2::foo;149 template <class T> Opaque<1> foo() { return Opaque<1>(); }150};151void 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>());156}157} // namespace more_constrained158} // namespace constrained_members159 160namespace heads_without_concepts {161struct base {162 template <int N, int M>163 int foo() { return 1; };164};165 166struct 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'}}170};171 172void 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'}}177}178} // namespace heads_without_concepts.179 180namespace GH146614 {181 182template <typename T>183struct base {184 template <typename A>185 void foo(A x)186 requires (requires{x;})187 {}188};189 190 191struct child : base<int> {192 using base<int>::foo;193 template <typename A>194 void foo(A x)195 requires (false)196 {}197};198 199}200