]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/SemaCXX/friend2.cpp
Vendor import of clang trunk r338150:
[FreeBSD/FreeBSD.git] / test / SemaCXX / friend2.cpp
1 // 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
6 void func1(int);
7 struct C1a {
8   friend void func1(int) {}  // expected-note{{previous definition is here}}
9 };
10 struct 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
18 void func2(int);
19 struct C2a {
20   friend void func2(int) {}
21 };
22 template<typename T> struct C2b {
23   friend void func2(int) {}
24 };
25
26 void func3(int);
27 struct C3a {
28   friend void func3(int) {}  // expected-note{{previous definition is here}}
29 };
30 template<typename T> struct C3b {
31   friend void func3(int) {}  // expected-error{{redefinition of 'func3'}}
32 };
33 C3b<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
39 void func4(int);
40 template<typename T> struct C4a {
41   friend void func4(int) {}
42 };
43 template<typename T> struct C4b {
44   friend void func4(int) {}
45 };
46
47
48 void func5(int);
49 template<typename T> struct C5a {
50   friend void func5(int) {}
51 };
52 template<typename T> struct C5b {
53   friend void func5(int) {}
54 };
55 C5a<long> c5a;
56
57 void func6(int);
58 template<typename T> struct C6a {
59   friend void func6(int) {}  // expected-note{{previous definition is here}}
60 };
61 template<typename T> struct C6b {
62   friend void func6(int) {}  // expected-error{{redefinition of 'func6'}}
63 };
64 C6a<long> c6a;
65 C6b<int*> c6b;  // expected-note{{in instantiation of template class 'C6b<int *>' requested here}}
66
67 void func7(int);
68 template<typename T> struct C7 {
69   friend void func7(int) {}  // expected-error{{redefinition of 'func7'}}
70                              // expected-note@-1{{previous definition is here}}
71 };
72 C7<long> c7a;
73 C7<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
79 void func8(int);  // expected-note{{previous declaration is here}}
80 template<typename T> struct C8a {
81   friend long func8(int);  // expected-error{{functions that differ only in their return type cannot be overloaded}}
82 };
83
84 void func9(int);  // expected-note{{previous declaration is here}}
85 template<typename T> struct C9a {
86   friend int func9(int);  // expected-error{{functions that differ only in their return type cannot be overloaded}}
87 };
88
89 void func10(int);  // expected-note{{previous declaration is here}}
90 template<typename T> struct C10a {
91   friend int func10(int);  // expected-error{{functions that differ only in their return type cannot be overloaded}}
92 };
93
94 void func_11();  // expected-note{{previous declaration is here}}
95 template<typename T> class C11 {
96   friend int func_11();  // expected-error{{functions that differ only in their return type cannot be overloaded}}
97 };
98
99 void func_12(int x);  // expected-note{{previous declaration is here}}
100 template<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
104 // Friend function with uninstantiated body is still a definition.
105
106 template<typename T> struct C20 {
107   friend void func_20() {} // expected-note{{previous definition is here}}
108 };
109 C20<int> c20i;
110 void func_20() {} // expected-error{{redefinition of 'func_20'}}
111
112 template<typename T> struct C21a {
113   friend void func_21() {} // expected-note{{previous definition is here}}
114 };
115 template<typename T> struct C21b {
116   friend void func_21() {} // expected-error{{redefinition of 'func_21'}}
117 };
118 C21a<int> c21ai;
119 C21b<int> c21bi; // expected-note{{in instantiation of template class 'C21b<int>' requested here}}
120
121 template<typename T> struct C22a {
122   friend void func_22() {} // expected-note{{previous definition is here}}
123 };
124 template<typename T> struct C22b {
125   friend void func_22();
126 };
127 C22a<int> c22ai;
128 C22b<int> c22bi;
129 void func_22() {} // expected-error{{redefinition of 'func_22'}}
130
131
132
133 namespace pr22307 {
134
135 struct t {
136   friend int leak(t);
137 };
138
139 template<typename v>
140 struct m {
141   friend int leak(t) { return sizeof(v); }  // expected-error{{redefinition of 'leak'}} expected-note{{previous definition is here}}
142 };
143
144 template struct m<char>;
145 template struct m<short>;  // expected-note{{in instantiation of template class 'pr22307::m<short>' requested here}}
146
147 int main() {
148   leak(t());
149 }
150
151 }
152
153 namespace pr17923 {
154
155 void f(unsigned long long);
156
157 template<typename T> struct X {
158   friend void f(unsigned long long) {
159      T t;
160   }
161 };
162
163 int main() { f(1234); }
164
165 }
166
167 namespace pr17923a {
168
169 int get();
170
171 template< int value >
172 class set {
173   friend int get()
174     { return value; } // return 0; is OK
175 };
176
177 template class set< 5 >;
178
179 int main() {
180   get();
181 }
182
183 }
184
185 namespace pr8035 {
186
187 void Function();
188
189 int main(int argc, char* argv[]) {
190   Function();
191 }
192
193 template <typename T>
194 struct Test {
195   friend void Function() { }
196 };
197
198 template class Test<int>;
199
200 }
201
202 namespace pr14785 {
203 template<typename T>
204 struct Somewhat {
205   void internal() const { }
206   friend void operator+(int const &, Somewhat<T> const &) {}  // expected-error{{redefinition of 'operator+'}}
207 };
208
209 void 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
214 namespace D30375 {
215 template <typename K> struct B {
216   template <typename A> bool insert(A &);
217 };
218
219 template <typename K>
220 template <typename A> bool B<K>::insert(A &x) { return x < x; }
221
222 template <typename K> class D {
223   B<K> t;
224
225 public:
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
231 template <typename K> bool operator<(const D<K> &, const D<K> &);
232
233 void func() {
234   D<D<int>> cache;
235   cache.insert();
236 }
237 }