// RUN: %clang_cc1 -fsyntax-only -verify -std=c++26 %s namespace t1 { template struct A { template friend auto cica(const A&, C) { return N; } }; template<> struct A<0> { template friend auto cica(const A<0>&, C); // expected-note@-1 {{declared here}} }; void test() { cica(A<0>{}, 0); // expected-error@-1 {{function 'cica' with deduced return type cannot be used before it is defined}} (void)A<1>{}; cica(A<0>{}, 0); } } // namespace t1 namespace t2 { template struct A { template friend auto cica(const A&, C) { return N; } }; template<> struct A<0> { template friend auto cica(const A<0>&, C); }; template {}, nullptr))> void MakeCica(); // expected-note@-1 {{candidate function}} template void MakeCica(A = {}); // expected-note@-1 {{candidate function}} void test() { MakeCica<0>(); MakeCica<0>(); // expected-error@-1 {{call to 'MakeCica' is ambiguous}} } } // namespace t2 namespace t3 { template struct A { template friend auto cica(const A&, C) { return N-1; } }; template<> struct A<0> { template friend auto cica(const A<0>&, C); }; template static constexpr bool MakeCica(int); template static constexpr bool MakeCica(short, A = {}); template , class Val = decltype(MakeCica(0))> static constexpr bool has_cica = Val{}; constexpr bool cica2 = has_cica<0> || has_cica<0>; } // namespace t3 namespace t4 { template struct A { template friend auto cica(const A&, C); }; template<> struct A<0> { template friend auto cica(const A<0>&, C) { C a; } }; template struct A<1>; void test() { cica(A<0>{}, 0); } } // namespace t4 namespace regression1 { template class A; template [[gnu::abi_tag("TAG")]] void foo(A); template struct A { friend void foo <>(A); }; template struct A; template [[gnu::abi_tag("TAG")]] void foo(A) {} template void foo(A); } // namespace regression1 namespace regression2 { template struct A { template static void f() { A::f(); } }; template <> template void A::f() { static_assert(__is_same(T, long)); } template void A::f(); } // namespace regression2 namespace GH139226 { struct FakeStream {}; template class BinaryTree; template FakeStream& operator<<(FakeStream& os, BinaryTree& b); template FakeStream& operator>>(FakeStream& os, BinaryTree& b) { return os; } template struct BinaryTree { T* root{}; friend FakeStream& operator<< (FakeStream& os, BinaryTree&) { // expected-error@-1 {{friend function specialization cannot be defined}} return os; } friend FakeStream& operator>> (FakeStream& os, BinaryTree&); }; void foo() { FakeStream fakeout; BinaryTree a{}; fakeout << a; fakeout >> a; } }