xref: /llvm-project/clang/test/SemaCXX/GH83461.cpp (revision 06bd74ba4ac5229f01b64772b49e025be5eb7b53)
1*06bd74baSErich Keane // RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s
2*06bd74baSErich Keane 
3*06bd74baSErich Keane struct S {
4*06bd74baSErich Keane   template<typename Ty = int>
foo(auto)5*06bd74baSErich Keane   friend void foo(auto){}
6*06bd74baSErich Keane 
7*06bd74baSErich Keane   template<typename Ty = int, typename Tz>
foo2()8*06bd74baSErich Keane   friend void foo2(){}
9*06bd74baSErich Keane };
10*06bd74baSErich Keane 
11*06bd74baSErich Keane template<typename T>
12*06bd74baSErich Keane struct TemplS {
13*06bd74baSErich Keane   template<typename Ty = int>
foo3(auto)14*06bd74baSErich Keane   friend void foo3(auto){}
15*06bd74baSErich Keane 
16*06bd74baSErich Keane   template<typename Ty = int, typename Tz>
foo4()17*06bd74baSErich Keane   friend void foo4(){}
18*06bd74baSErich Keane };
19*06bd74baSErich Keane 
Inst()20*06bd74baSErich Keane void Inst() {
21*06bd74baSErich Keane   TemplS<int>();
22*06bd74baSErich Keane }
23*06bd74baSErich Keane // expected-error@+2{{template parameter missing a default argument}}
24*06bd74baSErich Keane // expected-note@+1{{previous default template argument defined here}}
25*06bd74baSErich Keane template<typename T = int, typename U>
26*06bd74baSErich Keane struct ClassTempl{};
27*06bd74baSErich Keane 
28*06bd74baSErich Keane struct HasFriendClassTempl {
29*06bd74baSErich Keane   // expected-error@+1{{default template argument not permitted on a friend template}}
30*06bd74baSErich Keane   template<typename T = int, typename U>
31*06bd74baSErich Keane   friend struct Friend;
32*06bd74baSErich Keane 
33*06bd74baSErich Keane   // expected-error@+3{{cannot define a type in a friend declaration}}
34*06bd74baSErich Keane   // expected-error@+1{{default template argument not permitted on a friend template}}
35*06bd74baSErich Keane   template<typename T = int, typename U>
36*06bd74baSErich Keane   friend struct Friend2{};
37*06bd74baSErich Keane };
38*06bd74baSErich Keane 
39*06bd74baSErich Keane template<typename Ty>
40*06bd74baSErich Keane struct HasFriendClassTempl2 {
41*06bd74baSErich Keane   // expected-error@+3{{template parameter missing a default argument}}
42*06bd74baSErich Keane   // expected-note@+2{{previous default template argument defined here}}
43*06bd74baSErich Keane   // expected-note@#INST2{{in instantiation of template class}}
44*06bd74baSErich Keane   template<typename T = int, typename U>
45*06bd74baSErich Keane   friend struct Friend;
46*06bd74baSErich Keane };
47*06bd74baSErich Keane 
Inst2()48*06bd74baSErich Keane void Inst2() {
49*06bd74baSErich Keane   HasFriendClassTempl2<int>(); // #INST2
50*06bd74baSErich Keane }
51*06bd74baSErich Keane 
52*06bd74baSErich Keane // expected-error@+2{{template parameter missing a default argument}}
53*06bd74baSErich Keane // expected-note@+1{{previous default template argument defined here}}
54*06bd74baSErich Keane template<typename T = int, typename U>
55*06bd74baSErich Keane static constexpr U VarTempl;
56*06bd74baSErich Keane 
57*06bd74baSErich Keane // expected-error@+2{{template parameter missing a default argument}}
58*06bd74baSErich Keane // expected-note@+1{{previous default template argument defined here}}
59*06bd74baSErich Keane template<typename T = int, typename U>
60*06bd74baSErich Keane using TypeAlias = U;
61