1*56099d24SUtkarsh Saxena // RUN: %clang_cc1 -std=c++20 -verify %s 2*56099d24SUtkarsh Saxena 3*56099d24SUtkarsh Saxena namespace static_methods { 4*56099d24SUtkarsh Saxena template<class> concept False = false; 5*56099d24SUtkarsh Saxena 6*56099d24SUtkarsh Saxena struct Base { 7*56099d24SUtkarsh Saxena static void foo(auto); 8*56099d24SUtkarsh Saxena }; 9*56099d24SUtkarsh Saxena struct Derived : public Base { 10*56099d24SUtkarsh Saxena using Base::foo; 11*56099d24SUtkarsh Saxena static void foo(False auto); 12*56099d24SUtkarsh Saxena }; func()13*56099d24SUtkarsh Saxenavoid func() { 14*56099d24SUtkarsh Saxena Derived::foo(42); 15*56099d24SUtkarsh Saxena } 16*56099d24SUtkarsh Saxena } // namespace static_methods 17*56099d24SUtkarsh Saxena 18*56099d24SUtkarsh Saxena namespace constrained_members { 19*56099d24SUtkarsh Saxena template <unsigned n> struct Opaque {}; expect(Opaque<n> _)20*56099d24SUtkarsh Saxenatemplate <unsigned n> void expect(Opaque<n> _) {} 21*56099d24SUtkarsh Saxena 22*56099d24SUtkarsh Saxena struct Empty{}; 23*56099d24SUtkarsh Saxena constexpr int EmptySize = sizeof(Empty); 24*56099d24SUtkarsh Saxena 25*56099d24SUtkarsh Saxena template<typename T> concept IsEmpty = sizeof(T) == EmptySize; 26*56099d24SUtkarsh Saxena 27*56099d24SUtkarsh Saxena namespace base_members_not_hidden { 28*56099d24SUtkarsh Saxena struct base { 29*56099d24SUtkarsh Saxena template <typename T> fooconstrained_members::base_members_not_hidden::base30*56099d24SUtkarsh Saxena Opaque<0> foo() { return Opaque<0>(); }; 31*56099d24SUtkarsh Saxena }; 32*56099d24SUtkarsh Saxena 33*56099d24SUtkarsh Saxena struct bar1 : public base { 34*56099d24SUtkarsh Saxena using base::foo; 35*56099d24SUtkarsh Saxena template <typename T> requires IsEmpty<T> fooconstrained_members::base_members_not_hidden::bar136*56099d24SUtkarsh Saxena Opaque<1> foo() { return Opaque<1>(); }; 37*56099d24SUtkarsh Saxena }; 38*56099d24SUtkarsh Saxena 39*56099d24SUtkarsh Saxena struct bar2 : public base { 40*56099d24SUtkarsh Saxena using base::foo; 41*56099d24SUtkarsh Saxena template <IsEmpty T> fooconstrained_members::base_members_not_hidden::bar242*56099d24SUtkarsh Saxena Opaque<1> foo() { return Opaque<1>(); }; 43*56099d24SUtkarsh Saxena }; 44*56099d24SUtkarsh Saxena 45*56099d24SUtkarsh Saxena struct bar3 : public base { 46*56099d24SUtkarsh Saxena using base::foo; 47*56099d24SUtkarsh Saxena template <typename T> fooconstrained_members::base_members_not_hidden::bar348*56099d24SUtkarsh Saxena Opaque<1> foo() requires IsEmpty<T> { return Opaque<1>(); }; 49*56099d24SUtkarsh Saxena }; 50*56099d24SUtkarsh Saxena func()51*56099d24SUtkarsh Saxenavoid func() { 52*56099d24SUtkarsh Saxena expect<0>(base{}.foo<Empty>()); 53*56099d24SUtkarsh Saxena expect<0>(base{}.foo<int>()); 54*56099d24SUtkarsh Saxena expect<1>(bar1{}.foo<Empty>()); 55*56099d24SUtkarsh Saxena expect<0>(bar1{}.foo<int>()); 56*56099d24SUtkarsh Saxena expect<1>(bar2{}.foo<Empty>()); 57*56099d24SUtkarsh Saxena expect<0>(bar2{}.foo<int>()); 58*56099d24SUtkarsh Saxena expect<1>(bar3{}.foo<Empty>()); 59*56099d24SUtkarsh Saxena expect<0>(bar3{}.foo<int>()); 60*56099d24SUtkarsh Saxena } 61*56099d24SUtkarsh Saxena } 62*56099d24SUtkarsh Saxena namespace base_members_hidden { 63*56099d24SUtkarsh Saxena struct base1 { 64*56099d24SUtkarsh Saxena template <typename T> requires IsEmpty<T> fooconstrained_members::base_members_hidden::base165*56099d24SUtkarsh Saxena Opaque<0> foo() { return Opaque<0>(); }; // expected-note {{candidate function}} 66*56099d24SUtkarsh Saxena }; 67*56099d24SUtkarsh Saxena struct bar1 : public base1 { 68*56099d24SUtkarsh Saxena using base1::foo; 69*56099d24SUtkarsh Saxena template <typename T> requires IsEmpty<T> fooconstrained_members::base_members_hidden::bar170*56099d24SUtkarsh Saxena Opaque<1> foo() { return Opaque<1>(); }; 71*56099d24SUtkarsh Saxena }; 72*56099d24SUtkarsh Saxena struct base2 { 73*56099d24SUtkarsh Saxena template <IsEmpty T> fooconstrained_members::base_members_hidden::base274*56099d24SUtkarsh Saxena Opaque<0> foo() { return Opaque<0>(); }; 75*56099d24SUtkarsh Saxena }; 76*56099d24SUtkarsh Saxena struct bar2 : public base2 { 77*56099d24SUtkarsh Saxena using base2::foo; 78*56099d24SUtkarsh Saxena template <IsEmpty T> fooconstrained_members::base_members_hidden::bar279*56099d24SUtkarsh Saxena Opaque<1> foo() { return Opaque<1>(); }; 80*56099d24SUtkarsh Saxena }; 81*56099d24SUtkarsh Saxena struct baz : public base1 { 82*56099d24SUtkarsh Saxena using base1::foo; 83*56099d24SUtkarsh Saxena template <typename T> requires IsEmpty<T> && IsEmpty<T> fooconstrained_members::base_members_hidden::baz84*56099d24SUtkarsh Saxena Opaque<1> foo() { return Opaque<1>(); }; // expected-note {{candidate function}} 85*56099d24SUtkarsh Saxena }; func()86*56099d24SUtkarsh Saxenavoid func() { 87*56099d24SUtkarsh Saxena expect<0>(base1{}.foo<Empty>()); 88*56099d24SUtkarsh Saxena expect<1>(bar1{}.foo<Empty>()); 89*56099d24SUtkarsh Saxena expect<0>(base2{}.foo<Empty>()); 90*56099d24SUtkarsh Saxena expect<1>(bar2{}.foo<Empty>()); 91*56099d24SUtkarsh Saxena baz{}.foo<Empty>(); // expected-error {{call to member function 'foo' is ambiguous}} 92*56099d24SUtkarsh Saxena } 93*56099d24SUtkarsh Saxena } // namespace base_members_hidden 94*56099d24SUtkarsh Saxena 95*56099d24SUtkarsh Saxena namespace same_contraint_at_different_place { 96*56099d24SUtkarsh Saxena struct base { 97*56099d24SUtkarsh Saxena template <IsEmpty T> foo1constrained_members::same_contraint_at_different_place::base98*56099d24SUtkarsh Saxena void foo1() {}; // expected-note 2 {{candidate function}} 99*56099d24SUtkarsh Saxena template <typename T> requires IsEmpty<T> foo2constrained_members::same_contraint_at_different_place::base100*56099d24SUtkarsh Saxena void foo2() {}; // expected-note 2 {{candidate function}} 101*56099d24SUtkarsh Saxena template <typename T> foo3constrained_members::same_contraint_at_different_place::base102*56099d24SUtkarsh Saxena void foo3() requires IsEmpty<T> {}; // expected-note 2 {{candidate function}} 103*56099d24SUtkarsh Saxena }; 104*56099d24SUtkarsh Saxena struct bar1 : public base { 105*56099d24SUtkarsh Saxena using base::foo1; 106*56099d24SUtkarsh Saxena using base::foo2; 107*56099d24SUtkarsh Saxena using base::foo3; 108*56099d24SUtkarsh Saxena template <typename T> requires IsEmpty<T> foo1constrained_members::same_contraint_at_different_place::bar1109*56099d24SUtkarsh Saxena void foo1() {}; // expected-note {{candidate function}} 110*56099d24SUtkarsh Saxena template <IsEmpty T> foo2constrained_members::same_contraint_at_different_place::bar1111*56099d24SUtkarsh Saxena void foo2() {}; // expected-note {{candidate function}} 112*56099d24SUtkarsh Saxena template <IsEmpty T> foo3constrained_members::same_contraint_at_different_place::bar1113*56099d24SUtkarsh Saxena void foo3() {}; // expected-note {{candidate function}} 114*56099d24SUtkarsh Saxena }; 115*56099d24SUtkarsh Saxena struct bar2 : public base { 116*56099d24SUtkarsh Saxena using base::foo1; 117*56099d24SUtkarsh Saxena using base::foo2; 118*56099d24SUtkarsh Saxena using base::foo3; 119*56099d24SUtkarsh Saxena template <typename T> foo1constrained_members::same_contraint_at_different_place::bar2120*56099d24SUtkarsh Saxena void foo1() requires IsEmpty<T> {}; // expected-note {{candidate function}} 121*56099d24SUtkarsh Saxena template <typename T> foo2constrained_members::same_contraint_at_different_place::bar2122*56099d24SUtkarsh Saxena void foo2() requires IsEmpty<T> {}; // expected-note {{candidate function}} 123*56099d24SUtkarsh Saxena template <typename T> requires IsEmpty<T> foo3constrained_members::same_contraint_at_different_place::bar2124*56099d24SUtkarsh Saxena void foo3() {}; // expected-note {{candidate function}} 125*56099d24SUtkarsh Saxena }; func()126*56099d24SUtkarsh Saxenavoid func() { 127*56099d24SUtkarsh Saxena bar1{}.foo1<Empty>(); // expected-error {{call to member function 'foo1' is ambiguous}} 128*56099d24SUtkarsh Saxena bar1{}.foo2<Empty>(); // expected-error {{call to member function 'foo2' is ambiguous}} 129*56099d24SUtkarsh Saxena bar1{}.foo3<Empty>(); // expected-error {{call to member function 'foo3' is ambiguous}} 130*56099d24SUtkarsh Saxena bar2{}.foo1<Empty>(); // expected-error {{call to member function 'foo1' is ambiguous}} 131*56099d24SUtkarsh Saxena bar2{}.foo2<Empty>(); // expected-error {{call to member function 'foo2' is ambiguous}} 132*56099d24SUtkarsh Saxena bar2{}.foo3<Empty>(); // expected-error {{call to member function 'foo3' is ambiguous}} 133*56099d24SUtkarsh Saxena } 134*56099d24SUtkarsh Saxena } // namespace same_constraint_at_different_place 135*56099d24SUtkarsh Saxena 136*56099d24SUtkarsh Saxena namespace more_constrained { 137*56099d24SUtkarsh Saxena struct base1 { fooconstrained_members::more_constrained::base1138*56099d24SUtkarsh Saxena template <class T> Opaque<0> foo() { return Opaque<0>(); } 139*56099d24SUtkarsh Saxena }; 140*56099d24SUtkarsh Saxena struct derived1 : base1 { 141*56099d24SUtkarsh Saxena using base1::foo; fooconstrained_members::more_constrained::derived1142*56099d24SUtkarsh Saxena template <IsEmpty T> Opaque<1> foo() { return Opaque<1>(); } 143*56099d24SUtkarsh Saxena }; 144*56099d24SUtkarsh Saxena struct base2 { fooconstrained_members::more_constrained::base2145*56099d24SUtkarsh Saxena template <IsEmpty T> Opaque<0> foo() { return Opaque<0>(); } 146*56099d24SUtkarsh Saxena }; 147*56099d24SUtkarsh Saxena struct derived2 : base2 { 148*56099d24SUtkarsh Saxena using base2::foo; fooconstrained_members::more_constrained::derived2149*56099d24SUtkarsh Saxena template <class T> Opaque<1> foo() { return Opaque<1>(); } 150*56099d24SUtkarsh Saxena }; func()151*56099d24SUtkarsh Saxenavoid func() { 152*56099d24SUtkarsh Saxena expect<0>(derived1{}.foo<int>()); 153*56099d24SUtkarsh Saxena expect<1>(derived1{}.foo<Empty>()); 154*56099d24SUtkarsh Saxena expect<0>(derived2{}.foo<Empty>()); 155*56099d24SUtkarsh Saxena expect<1>(derived2{}.foo<int>()); 156*56099d24SUtkarsh Saxena } 157*56099d24SUtkarsh Saxena } // namespace more_constrained 158*56099d24SUtkarsh Saxena } // namespace constrained_members 159*56099d24SUtkarsh Saxena 160*56099d24SUtkarsh Saxena namespace heads_without_concepts { 161*56099d24SUtkarsh Saxena struct base { 162*56099d24SUtkarsh Saxena template <int N, int M> fooheads_without_concepts::base163*56099d24SUtkarsh Saxena int foo() { return 1; }; 164*56099d24SUtkarsh Saxena }; 165*56099d24SUtkarsh Saxena 166*56099d24SUtkarsh Saxena struct bar : public base { 167*56099d24SUtkarsh Saxena using base::foo; 168*56099d24SUtkarsh Saxena template <int N> fooheads_without_concepts::bar169*56099d24SUtkarsh Saxena int foo() { return 2; }; // expected-note {{candidate template ignored: substitution failure: too many template arguments for function template 'foo'}} 170*56099d24SUtkarsh Saxena }; 171*56099d24SUtkarsh Saxena func()172*56099d24SUtkarsh Saxenavoid func() { 173*56099d24SUtkarsh Saxena bar f; 174*56099d24SUtkarsh Saxena f.foo<10>(); 175*56099d24SUtkarsh Saxena // FIXME(GH58571): bar::foo should not hide base::foo. 176*56099d24SUtkarsh Saxena f.foo<10, 10>(); // expected-error {{no matching member function for call to 'foo'}} 177*56099d24SUtkarsh Saxena } 178*56099d24SUtkarsh Saxena } // namespace heads_without_concepts. 179