xref: /llvm-project/clang/test/SemaTemplate/GH55509.cpp (revision 07a0e2be86f33beb6d519a3d466b95c2257e93cb)
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