1 // RUN: %clang_cc1 -std=c++20 -verify %s 2 3 namespace static_methods { 4 template<class> concept False = false; 5 6 struct Base { 7 static void foo(auto); 8 }; 9 struct Derived : public Base { 10 using Base::foo; 11 static void foo(False auto); 12 }; func()13void func() { 14 Derived::foo(42); 15 } 16 } // namespace static_methods 17 18 namespace constrained_members { 19 template <unsigned n> struct Opaque {}; expect(Opaque<n> _)20template <unsigned n> void expect(Opaque<n> _) {} 21 22 struct Empty{}; 23 constexpr int EmptySize = sizeof(Empty); 24 25 template<typename T> concept IsEmpty = sizeof(T) == EmptySize; 26 27 namespace base_members_not_hidden { 28 struct base { 29 template <typename T> fooconstrained_members::base_members_not_hidden::base30 Opaque<0> foo() { return Opaque<0>(); }; 31 }; 32 33 struct bar1 : public base { 34 using base::foo; 35 template <typename T> requires IsEmpty<T> fooconstrained_members::base_members_not_hidden::bar136 Opaque<1> foo() { return Opaque<1>(); }; 37 }; 38 39 struct bar2 : public base { 40 using base::foo; 41 template <IsEmpty T> fooconstrained_members::base_members_not_hidden::bar242 Opaque<1> foo() { return Opaque<1>(); }; 43 }; 44 45 struct bar3 : public base { 46 using base::foo; 47 template <typename T> fooconstrained_members::base_members_not_hidden::bar348 Opaque<1> foo() requires IsEmpty<T> { return Opaque<1>(); }; 49 }; 50 func()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 } 62 namespace base_members_hidden { 63 struct base1 { 64 template <typename T> requires IsEmpty<T> fooconstrained_members::base_members_hidden::base165 Opaque<0> foo() { return Opaque<0>(); }; // expected-note {{candidate function}} 66 }; 67 struct bar1 : public base1 { 68 using base1::foo; 69 template <typename T> requires IsEmpty<T> fooconstrained_members::base_members_hidden::bar170 Opaque<1> foo() { return Opaque<1>(); }; 71 }; 72 struct base2 { 73 template <IsEmpty T> fooconstrained_members::base_members_hidden::base274 Opaque<0> foo() { return Opaque<0>(); }; 75 }; 76 struct bar2 : public base2 { 77 using base2::foo; 78 template <IsEmpty T> fooconstrained_members::base_members_hidden::bar279 Opaque<1> foo() { return Opaque<1>(); }; 80 }; 81 struct baz : public base1 { 82 using base1::foo; 83 template <typename T> requires IsEmpty<T> && IsEmpty<T> fooconstrained_members::base_members_hidden::baz84 Opaque<1> foo() { return Opaque<1>(); }; // expected-note {{candidate function}} 85 }; func()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_hidden 94 95 namespace same_contraint_at_different_place { 96 struct base { 97 template <IsEmpty T> foo1constrained_members::same_contraint_at_different_place::base98 void foo1() {}; // expected-note 2 {{candidate function}} 99 template <typename T> requires IsEmpty<T> foo2constrained_members::same_contraint_at_different_place::base100 void foo2() {}; // expected-note 2 {{candidate function}} 101 template <typename T> foo3constrained_members::same_contraint_at_different_place::base102 void foo3() requires IsEmpty<T> {}; // expected-note 2 {{candidate function}} 103 }; 104 struct bar1 : public base { 105 using base::foo1; 106 using base::foo2; 107 using base::foo3; 108 template <typename T> requires IsEmpty<T> foo1constrained_members::same_contraint_at_different_place::bar1109 void foo1() {}; // expected-note {{candidate function}} 110 template <IsEmpty T> foo2constrained_members::same_contraint_at_different_place::bar1111 void foo2() {}; // expected-note {{candidate function}} 112 template <IsEmpty T> foo3constrained_members::same_contraint_at_different_place::bar1113 void foo3() {}; // expected-note {{candidate function}} 114 }; 115 struct bar2 : public base { 116 using base::foo1; 117 using base::foo2; 118 using base::foo3; 119 template <typename T> foo1constrained_members::same_contraint_at_different_place::bar2120 void foo1() requires IsEmpty<T> {}; // expected-note {{candidate function}} 121 template <typename T> foo2constrained_members::same_contraint_at_different_place::bar2122 void foo2() requires IsEmpty<T> {}; // expected-note {{candidate function}} 123 template <typename T> requires IsEmpty<T> foo3constrained_members::same_contraint_at_different_place::bar2124 void foo3() {}; // expected-note {{candidate function}} 125 }; func()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_place 135 136 namespace more_constrained { 137 struct base1 { fooconstrained_members::more_constrained::base1138 template <class T> Opaque<0> foo() { return Opaque<0>(); } 139 }; 140 struct derived1 : base1 { 141 using base1::foo; fooconstrained_members::more_constrained::derived1142 template <IsEmpty T> Opaque<1> foo() { return Opaque<1>(); } 143 }; 144 struct base2 { fooconstrained_members::more_constrained::base2145 template <IsEmpty T> Opaque<0> foo() { return Opaque<0>(); } 146 }; 147 struct derived2 : base2 { 148 using base2::foo; fooconstrained_members::more_constrained::derived2149 template <class T> Opaque<1> foo() { return Opaque<1>(); } 150 }; func()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_constrained 158 } // namespace constrained_members 159 160 namespace heads_without_concepts { 161 struct base { 162 template <int N, int M> fooheads_without_concepts::base163 int foo() { return 1; }; 164 }; 165 166 struct bar : public base { 167 using base::foo; 168 template <int N> fooheads_without_concepts::bar169 int foo() { return 2; }; // expected-note {{candidate template ignored: substitution failure: too many template arguments for function template 'foo'}} 170 }; 171 func()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