[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / SemaTemplate / friend.cpp
blob9a1ed46812ca9e17d215aecdd2a43694981bf230
1 // RUN: %clang_cc1 -fsyntax-only -verify %s
2 template<typename T> struct A {
3 struct B { };
5 friend struct B;
6 };
8 void f() {
9 A<int>::B b;
12 struct C0 {
13 friend struct A<int>;
16 namespace PR6770 {
17 namespace N {
18 int f1(int);
20 using namespace N;
22 namespace M {
23 float f1(float);
25 using M::f1;
27 template<typename T> void f1(T, T);
28 template <class T>
29 void f() {
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
38 // inlined.
39 void foo();
40 void bar();
41 template <typename T>
42 class C {
43 friend void foo();
44 friend inline void bar();
46 inline void foo() {}
47 inline void bar() {}
48 C<int> c;
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'}}
63 X1<int> xi;
64 X2<double> xd; // expected-note {{in instantiation of}}
65 X2<int> x2i;
67 struct Y {
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'}}
80 Z1<int> zi;
81 Z2<double> zd; // expected-note {{in instantiation of}}
82 Z2<int> z2i;
84 template<typename T>
85 struct OK {
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*);
95 friend void Y::f(T*);
96 friend void Y::f<T>(T*);
97 friend void Y::nondep<int>();
98 friend void Y::nondep<T>();
100 OK<float> ok;
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>).
110 namespace N {}
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); }
123 B<int> bi; // ok?!
126 namespace PR37556 {
127 inline namespace N { int x1, x2, y1, y2; } // expected-note 2{{previous}}
128 struct X {
129 friend void x1(int);
130 friend void PR37556::x2(int); // expected-error {{different kind}}
132 template<typename T> struct Y {
133 friend void y1(T);
134 friend void PR37556::y2(T); // expected-error {{different kind}}
136 template struct Y<int>;
137 template<typename T> struct Z {
138 friend void z1(T);
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'}}
152 namespace GH61851 {
153 namespace A {
154 inline namespace B {
155 constexpr struct {} foo;
158 template <typename T>
159 class Bar {
160 template <typename U>
161 friend void foo(U &&arg) {} // no diagnostic expected
165 void foobar() {
166 A::Bar<int> b;