148 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -verify -std=c++26 %s2 3namespace 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 t123namespace 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 t248namespace 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 t370namespace 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 t487namespace 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 regression1102namespace regression2 {103 template <class> struct A {104 template <class T> static void f() {105 A<int>::f<T>();106 }107 };108 template <> template <class T> void A<int>::f() {109 static_assert(__is_same(T, long));110 }111 template void A<void>::f<long>();112} // namespace regression2113 114namespace GH139226 {115 116struct FakeStream {};117 118template <typename T>119class BinaryTree;120 121template <typename T>122FakeStream& operator<<(FakeStream& os, BinaryTree<T>& b);123 124template <typename T>125FakeStream& operator>>(FakeStream& os, BinaryTree<T>& b) {126 return os;127}128 129template <typename T>130struct BinaryTree {131 T* root{};132 friend FakeStream& operator<< <T>(FakeStream& os, BinaryTree&) {133 // expected-error@-1 {{friend function specialization cannot be defined}}134 return os;135 }136 137 friend FakeStream& operator>> <T>(FakeStream& os, BinaryTree&);138};139 140void foo() {141 FakeStream fakeout;142 BinaryTree<int> a{};143 fakeout << a;144 fakeout >> a;145}146 147}148