xref: /llvm-project/clang/test/CXX/temp/temp.spec/temp.expl.spec/p14-23.cpp (revision 8282c58d9b1cd5b6df89ee3f68438fe0ee672f7f)
134ae2265SKrystian Stasiowski // RUN: %clang_cc1 -std=c++20 -verify %s
234ae2265SKrystian Stasiowski 
3b9183d0dSKrystian Stasiowski namespace N0 {
434ae2265SKrystian Stasiowski   template<int I>
534ae2265SKrystian Stasiowski   concept C = I >= 4;
634ae2265SKrystian Stasiowski 
734ae2265SKrystian Stasiowski   template<int I>
834ae2265SKrystian Stasiowski   concept D = I < 8;
934ae2265SKrystian Stasiowski 
1034ae2265SKrystian Stasiowski   template<int I>
11*8282c58dSc8ef   struct A { // #defined-here
1234ae2265SKrystian Stasiowski     constexpr static int f() { return 0; }
1334ae2265SKrystian Stasiowski     constexpr static int f() requires C<I> && D<I> { return 1; }
1434ae2265SKrystian Stasiowski     constexpr static int f() requires C<I> { return 2; }
1534ae2265SKrystian Stasiowski 
1634ae2265SKrystian Stasiowski     constexpr static int g() requires C<I> { return 0; } // #candidate-0
1734ae2265SKrystian Stasiowski     constexpr static int g() requires D<I> { return 1; } // #candidate-1
1834ae2265SKrystian Stasiowski 
1934ae2265SKrystian Stasiowski     constexpr static int h() requires C<I> { return 0; } // expected-note {{member declaration nearly matches}}
2034ae2265SKrystian Stasiowski   };
2134ae2265SKrystian Stasiowski 
2234ae2265SKrystian Stasiowski   template<>
2334ae2265SKrystian Stasiowski   constexpr int A<2>::f() { return 3; }
2434ae2265SKrystian Stasiowski 
2534ae2265SKrystian Stasiowski   template<>
2634ae2265SKrystian Stasiowski   constexpr int A<4>::f() { return 4; }
2734ae2265SKrystian Stasiowski 
2834ae2265SKrystian Stasiowski   template<>
2934ae2265SKrystian Stasiowski   constexpr int A<8>::f() { return 5; }
3034ae2265SKrystian Stasiowski 
3134ae2265SKrystian Stasiowski   static_assert(A<3>::f() == 0);
3234ae2265SKrystian Stasiowski   static_assert(A<5>::f() == 1);
3334ae2265SKrystian Stasiowski   static_assert(A<9>::f() == 2);
3434ae2265SKrystian Stasiowski   static_assert(A<2>::f() == 3);
3534ae2265SKrystian Stasiowski   static_assert(A<4>::f() == 4);
3634ae2265SKrystian Stasiowski   static_assert(A<8>::f() == 5);
3734ae2265SKrystian Stasiowski 
3834ae2265SKrystian Stasiowski   template<>
3934ae2265SKrystian Stasiowski   constexpr int A<0>::g() { return 2; }
4034ae2265SKrystian Stasiowski 
4134ae2265SKrystian Stasiowski   template<>
4234ae2265SKrystian Stasiowski   constexpr int A<8>::g() { return 3; }
4334ae2265SKrystian Stasiowski 
4434ae2265SKrystian Stasiowski   template<>
45b9183d0dSKrystian Stasiowski   constexpr int A<6>::g() { return 4; } // expected-error {{ambiguous member function specialization 'N0::A<6>::g' of 'N0::A::g'}}
4634ae2265SKrystian Stasiowski                                         // expected-note@#candidate-0 {{member function specialization matches 'g'}}
4734ae2265SKrystian Stasiowski                                         // expected-note@#candidate-1 {{member function specialization matches 'g'}}
4834ae2265SKrystian Stasiowski 
4934ae2265SKrystian Stasiowski   static_assert(A<9>::g() == 0);
5034ae2265SKrystian Stasiowski   static_assert(A<1>::g() == 1);
5134ae2265SKrystian Stasiowski   static_assert(A<0>::g() == 2);
5234ae2265SKrystian Stasiowski   static_assert(A<8>::g() == 3);
5334ae2265SKrystian Stasiowski 
5434ae2265SKrystian Stasiowski   template<>
5534ae2265SKrystian Stasiowski   constexpr int A<4>::h() { return 1; }
5634ae2265SKrystian Stasiowski 
5734ae2265SKrystian Stasiowski   template<>
58b9183d0dSKrystian Stasiowski   constexpr int A<0>::h() { return 2; } // expected-error {{out-of-line definition of 'h' does not match any declaration in 'N0::A<0>'}}
59*8282c58dSc8ef                                         // expected-note@#defined-here {{defined here}}
6034ae2265SKrystian Stasiowski 
6134ae2265SKrystian Stasiowski   static_assert(A<5>::h() == 0);
6234ae2265SKrystian Stasiowski   static_assert(A<4>::h() == 1);
63b9183d0dSKrystian Stasiowski } // namespace N0
64b9183d0dSKrystian Stasiowski 
65b9183d0dSKrystian Stasiowski namespace N1 {
66b9183d0dSKrystian Stasiowski   template<int I>
67b9183d0dSKrystian Stasiowski   concept C = I > 0;
68b9183d0dSKrystian Stasiowski 
69b9183d0dSKrystian Stasiowski   template<int I>
70b9183d0dSKrystian Stasiowski   concept D = I > 1;
71b9183d0dSKrystian Stasiowski 
72b9183d0dSKrystian Stasiowski   template<int I>
73b9183d0dSKrystian Stasiowski   concept E = I > 2;
74b9183d0dSKrystian Stasiowski 
75b9183d0dSKrystian Stasiowski   template<int I>
76b9183d0dSKrystian Stasiowski   struct A {
77b9183d0dSKrystian Stasiowski     void f() requires C<I> && D<I>; // expected-note {{member function specialization matches 'f'}}
78b9183d0dSKrystian Stasiowski     void f() requires C<I> && E<I>; // expected-note {{member function specialization matches 'f'}}
79b9183d0dSKrystian Stasiowski     void f() requires C<I> && D<I> && true; // expected-note {{member function specialization matches 'f'}}
80b9183d0dSKrystian Stasiowski 
81b9183d0dSKrystian Stasiowski     void g() requires C<I> && E<I>; // expected-note {{member function specialization matches 'g'}}
82b9183d0dSKrystian Stasiowski     void g() requires C<I> && D<I>; // expected-note {{member function specialization matches 'g'}}
83b9183d0dSKrystian Stasiowski     void g() requires C<I> && D<I> && true; // expected-note {{member function specialization matches 'g'}}
84b9183d0dSKrystian Stasiowski   };
85b9183d0dSKrystian Stasiowski 
86b9183d0dSKrystian Stasiowski   template<>
87b9183d0dSKrystian Stasiowski   void A<3>::f(); // expected-error {{ambiguous member function specialization 'N1::A<3>::f' of 'N1::A::f'}}
88b9183d0dSKrystian Stasiowski 
89b9183d0dSKrystian Stasiowski   template<>
90b9183d0dSKrystian Stasiowski   void A<3>::g(); // expected-error {{ambiguous member function specialization 'N1::A<3>::g' of 'N1::A::g'}}
91b9183d0dSKrystian Stasiowski } // namespace N1
92