1 // RUN: %clang_cc1 -fsyntax-only -verify %s
2 template<typename T
> struct A
{
27 template<typename T
> void f1(T
, T
);
30 friend class f
; // expected-error{{'friend' used outside of class}}
31 friend class f1
; // expected-error{{'friend' used outside of class}}
35 namespace friend_redecl_inline
{
36 // We had a bug where instantiating the foo friend declaration would check the
37 // defined-ness of the most recent decl while checking if the canonical decl was
44 friend inline void bar();
51 namespace qualified_friend
{
52 void f(int); // expected-note 2{{type mismatch at 1st parameter}}
53 template<typename T
> void f(T
*); // expected-note 2{{could not match 'T *' against 'double'}}
54 template<typename T
> void nondep();
56 template<typename
> struct X1
{
57 friend void qualified_friend::f(double); // expected-error {{friend declaration of 'f' does not match any declaration in namespace 'qualified_friend'}}
58 friend void qualified_friend::g(); // expected-error {{friend declaration of 'g' does not match any declaration in namespace 'qualified_friend'}}
60 template<typename T
> struct X2
{
61 friend void qualified_friend::f(T
); // expected-error {{friend declaration of 'f' does not match any declaration in namespace 'qualified_friend'}}
64 X2
<double> xd
; // expected-note {{in instantiation of}}
68 void f(int); // expected-note 2{{type mismatch at 1st parameter}}
69 template<typename T
> void f(T
*); // expected-note 2{{could not match 'T *' against 'double'}}
70 template<typename T
> void nondep();
73 template<typename
> struct Z1
{
74 friend void Y::f(double); // expected-error {{friend declaration of 'f' does not match any declaration in 'qualified_friend::Y'}}
75 friend void Y::g(); // expected-error {{friend declaration of 'g' does not match any declaration in 'qualified_friend::Y'}}
77 template<typename T
> struct Z2
{
78 friend void Y::f(T
); // expected-error {{friend declaration of 'f' does not match any declaration in 'qualified_friend::Y'}}
81 Z2
<double> zd
; // expected-note {{in instantiation of}}
86 friend void qualified_friend::f(int);
87 friend void qualified_friend::f(int*);
88 friend void qualified_friend::f(T
*);
89 friend void qualified_friend::f
<T
>(T
*);
90 friend void qualified_friend::nondep
<int>();
91 friend void qualified_friend::nondep
<T
>();
93 friend void Y::f(int);
94 friend void Y::f(int*);
96 friend void Y::f
<T
>(T
*);
97 friend void Y::nondep
<int>();
98 friend void Y::nondep
<T
>();
103 namespace qualified_friend_finds_nothing
{
104 // FIXME: The status of this example is unclear. For now, we diagnose if the
105 // qualified declaration has nothing it can redeclare, but allow qualified
106 // lookup to find later-declared function templates during instantiation.
108 // This matches the behavior of GCC, EDG, ICC, and MSVC (except that GCC and
109 // ICC bizarrely accept the instantiation of B<float>).
112 template<typename T
> struct A
{
113 friend void N::f(T
); // expected-error {{friend declaration of 'f' does not match}}
115 namespace N
{ void f(); } // expected-note {{different number of parameters}}
117 template<typename T
> struct B
{
118 friend void N::f(T
); // expected-error {{friend declaration of 'f' does not match}}
120 B
<float> bf
; // expected-note {{in instantiation of}}
122 namespace N
{ void f(int); }
127 inline namespace N
{ int x1
, x2
, y1
, y2
; } // expected-note 2{{previous}}
130 friend void PR37556::x2(int); // expected-error {{different kind}}
132 template<typename T
> struct Y
{
134 friend void PR37556::y2(T
); // expected-error {{different kind}}
136 template struct Y
<int>;
137 template<typename T
> struct Z
{
139 friend void PR37556::z2(T
); // expected-error {{does not match any}}
141 inline namespace N
{ int z1
, z2
; }
142 template struct Z
<int>;
145 namespace PR42513_comment3
{
146 template<typename X
> struct T
{ friend auto f(X
*) { return nullptr; } };
147 struct X1
{ friend auto f(X1
*); };
148 template struct T
<X1
>;
149 int n
= f((X1
*)nullptr); // expected-error {{cannot initialize a variable of type 'int' with an rvalue of type 'std::nullptr_t'}}
155 constexpr struct {} foo
;
158 template <typename T
>
160 template <typename U
>
161 friend void foo(U
&&arg
) {} // no diagnostic expected