1 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++26 %s 2 3 namespace t1 { 4 template<int N> struct A { 5 template<class C> friend auto cica(const A<N-1>&, C) { 6 return N; 7 } 8 }; 9 10 template<> struct A<0> { 11 template<class C> friend auto cica(const A<0>&, C); 12 // expected-note@-1 {{declared here}} 13 }; 14 15 void test() { 16 cica(A<0>{}, 0); 17 // expected-error@-1 {{function 'cica<int>' with deduced return type cannot be used before it is defined}} 18 19 (void)A<1>{}; 20 cica(A<0>{}, 0); 21 } 22 } // namespace t1 23 namespace t2 { 24 template<int N> struct A { 25 template<class C> friend auto cica(const A<N-1>&, C) { 26 return N; 27 } 28 }; 29 30 template<> struct A<0> { 31 template<class C> friend auto cica(const A<0>&, C); 32 }; 33 34 template <int N, class = decltype(cica(A<N>{}, nullptr))> 35 void MakeCica(); 36 // expected-note@-1 {{candidate function}} 37 38 template <int N> void MakeCica(A<N+1> = {}); 39 // expected-note@-1 {{candidate function}} 40 41 void test() { 42 MakeCica<0>(); 43 44 MakeCica<0>(); 45 // expected-error@-1 {{call to 'MakeCica' is ambiguous}} 46 } 47 } // namespace t2 48 namespace t3 { 49 template<int N> struct A { 50 template<class C> friend auto cica(const A<N-1>&, C) { 51 return N-1; 52 } 53 }; 54 55 template<> struct A<0> { 56 template<class C> friend auto cica(const A<0>&, C); 57 }; 58 59 template <int N, class AT, class = decltype(cica(AT{}, nullptr))> 60 static constexpr bool MakeCica(int); 61 62 template <int N, class AT> 63 static constexpr bool MakeCica(short, A<N+1> = {}); 64 65 template <int N, class AT = A<N>, class Val = decltype(MakeCica<N, AT>(0))> 66 static constexpr bool has_cica = Val{}; 67 68 constexpr bool cica2 = has_cica<0> || has_cica<0>; 69 } // namespace t3 70 namespace t4 { 71 template<int N> struct A { 72 template<class C> friend auto cica(const A<N-1>&, C); 73 }; 74 75 template<> struct A<0> { 76 template<class C> friend auto cica(const A<0>&, C) { 77 C a; 78 } 79 }; 80 81 template struct A<1>; 82 83 void test() { 84 cica(A<0>{}, 0); 85 } 86 } // namespace t4 87 namespace regression1 { 88 template <class> class A; 89 90 template <class T> [[gnu::abi_tag("TAG")]] void foo(A<T>); 91 92 template <class> struct A { 93 friend void foo <>(A); 94 }; 95 96 template struct A<int>; 97 98 template <class T> [[gnu::abi_tag("TAG")]] void foo(A<T>) {} 99 100 template void foo<int>(A<int>); 101 } // namespace regression1 102