blob: 8eacdeb19c62e81eac46fd1d605106489c6ab61e [file] [log] [blame]
Serge Pavlov06b7a872016-10-04 10:11:43 +00001// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
2
3// If a friend function is defined in several non-template classes,
4// it is an error.
5
6void func1(int);
7struct C1a {
8 friend void func1(int) {} // expected-note{{previous definition is here}}
9};
10struct C1b {
11 friend void func1(int) {} // expected-error{{redefinition of 'func1'}}
12};
13
14
15// If a friend function is defined in both non-template and template
16// classes it is an error only if the template is instantiated.
17
18void func2(int);
19struct C2a {
20 friend void func2(int) {}
21};
22template<typename T> struct C2b {
23 friend void func2(int) {}
24};
25
26void func3(int);
27struct C3a {
28 friend void func3(int) {} // expected-note{{previous definition is here}}
29};
30template<typename T> struct C3b {
31 friend void func3(int) {} // expected-error{{redefinition of 'func3'}}
32};
33C3b<long> c3; // expected-note{{in instantiation of template class 'C3b<long>' requested here}}
34
35
36// If a friend function is defined in several template classes it is an error
37// only if several templates are instantiated.
38
39void func4(int);
40template<typename T> struct C4a {
41 friend void func4(int) {}
42};
43template<typename T> struct C4b {
44 friend void func4(int) {}
45};
46
47
48void func5(int);
49template<typename T> struct C5a {
50 friend void func5(int) {}
51};
52template<typename T> struct C5b {
53 friend void func5(int) {}
54};
55C5a<long> c5a;
56
57void func6(int);
58template<typename T> struct C6a {
59 friend void func6(int) {} // expected-note{{previous definition is here}}
60};
61template<typename T> struct C6b {
62 friend void func6(int) {} // expected-error{{redefinition of 'func6'}}
63};
64C6a<long> c6a;
65C6b<int*> c6b; // expected-note{{in instantiation of template class 'C6b<int *>' requested here}}
66
67void func7(int);
68template<typename T> struct C7 {
69 friend void func7(int) {} // expected-error{{redefinition of 'func7'}}
70 // expected-note@-1{{previous definition is here}}
71};
72C7<long> c7a;
73C7<int*> c7b; // expected-note{{in instantiation of template class 'C7<int *>' requested here}}
74
75
76// Even if clases are not instantiated and hence friend functions defined in them are not
77// available, their declarations can be checked.
78
79void func8(int); // expected-note{{previous declaration is here}}
80template<typename T> struct C8a {
81 friend long func8(int); // expected-error{{functions that differ only in their return type cannot be overloaded}}
82};
83
84void func9(int); // expected-note{{previous declaration is here}}
85template<typename T> struct C9a {
86 friend int func9(int); // expected-error{{functions that differ only in their return type cannot be overloaded}}
87};
88
89void func10(int); // expected-note{{previous declaration is here}}
90template<typename T> struct C10a {
91 friend int func10(int); // expected-error{{functions that differ only in their return type cannot be overloaded}}
92};
93
94void func_11(); // expected-note{{previous declaration is here}}
95template<typename T> class C11 {
96 friend int func_11(); // expected-error{{functions that differ only in their return type cannot be overloaded}}
97};
98
99void func_12(int x); // expected-note{{previous declaration is here}}
100template<typename T> class C12 {
101 friend void func_12(int x = 0); // expected-error{{friend declaration specifying a default argument must be the only declaration}}
102};
103
Serge Pavlove6e534c2018-03-01 07:04:11 +0000104// Friend function with uninstantiated body is still a definition.
105
106template<typename T> struct C20 {
107 friend void func_20() {} // expected-note{{previous definition is here}}
108};
109C20<int> c20i;
110void func_20() {} // expected-error{{redefinition of 'func_20'}}
111
112template<typename T> struct C21a {
113 friend void func_21() {} // expected-note{{previous definition is here}}
114};
115template<typename T> struct C21b {
116 friend void func_21() {} // expected-error{{redefinition of 'func_21'}}
117};
118C21a<int> c21ai;
119C21b<int> c21bi; // expected-note{{in instantiation of template class 'C21b<int>' requested here}}
120
121template<typename T> struct C22a {
122 friend void func_22() {} // expected-note{{previous definition is here}}
123};
124template<typename T> struct C22b {
125 friend void func_22();
126};
127C22a<int> c22ai;
128C22b<int> c22bi;
129void func_22() {} // expected-error{{redefinition of 'func_22'}}
130
131
Serge Pavlov06b7a872016-10-04 10:11:43 +0000132
133namespace pr22307 {
134
135struct t {
136 friend int leak(t);
137};
138
139template<typename v>
140struct m {
141 friend int leak(t) { return sizeof(v); } // expected-error{{redefinition of 'leak'}} expected-note{{previous definition is here}}
142};
143
144template struct m<char>;
145template struct m<short>; // expected-note{{in instantiation of template class 'pr22307::m<short>' requested here}}
146
147int main() {
148 leak(t());
149}
150
151}
152
153namespace pr17923 {
154
155void f(unsigned long long);
156
157template<typename T> struct X {
158 friend void f(unsigned long long) {
159 T t;
160 }
161};
162
163int main() { f(1234); }
164
165}
166
167namespace pr17923a {
168
169int get();
170
171template< int value >
172class set {
173 friend int get()
174 { return value; } // return 0; is OK
175};
176
177template class set< 5 >;
178
179int main() {
180 get();
181}
182
183}
184
185namespace pr8035 {
186
187void Function();
188
189int main(int argc, char* argv[]) {
190 Function();
191}
192
193template <typename T>
194struct Test {
195 friend void Function() { }
196};
197
198template class Test<int>;
199
200}
Serge Pavlov25dbe1a2017-06-21 12:46:57 +0000201
202namespace pr14785 {
203template<typename T>
204struct Somewhat {
205 void internal() const { }
206 friend void operator+(int const &, Somewhat<T> const &) {} // expected-error{{redefinition of 'operator+'}}
207};
208
209void operator+(int const &, Somewhat<char> const &x) { // expected-note {{previous definition is here}}
210 x.internal(); // expected-note{{in instantiation of template class 'pr14785::Somewhat<char>' requested here}}
211}
212}
213
214namespace D30375 {
215template <typename K> struct B {
216 template <typename A> bool insert(A &);
217};
218
219template <typename K>
220template <typename A> bool B<K>::insert(A &x) { return x < x; }
221
222template <typename K> class D {
223 B<K> t;
224
225public:
226 K x;
227 bool insert() { return t.insert(x); }
228 template <typename K1> friend bool operator<(const D<K1> &, const D<K1> &);
229};
230
231template <typename K> bool operator<(const D<K> &, const D<K> &);
232
233void func() {
234 D<D<int>> cache;
235 cache.insert();
236}
237}