[clang] Handle __declspec() attributes in using
[llvm-project.git] / clang / test / SemaTemplate / concepts-friends.cpp
blob3a9b308a65c5d6e5349af034bc08432c806eddfa
1 // RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s
3 template <typename T>
4 concept constraint = false;
5 namespace temp_friend_9 {
6 // A non-template friend declaration with a requires-clause shall be a
7 // definition. ...Such a constrained friend function ... does not declare the
8 // same function or function template as a declaration in any other scope.
9 template <typename T>
10 struct NonTemplateFriend {
11 friend void foo()
12 requires true
16 // A friend function template with a constraint that depends on a template
17 // parameter from an enclosing template shall be a definition. Such a ...
18 // function template declaration does not declare the same function or
19 // function template as a declaration in any other scope.
20 template <typename T>
21 struct TemplateFromEnclosing {
22 template <typename U>
23 friend void foo()
24 requires constraint<T>
27 T variable;
28 template <typename U>
29 friend void foo2()
30 requires constraint<decltype(variable)>
33 template <typename U>
34 friend void foo3(T parmvar)
35 requires constraint<decltype(parmvar)>
38 template <typename U>
39 friend void foo4()
40 requires requires(T &req) { (void)req; }
43 using Alias = T;
44 template <typename U>
45 friend void foo5()
46 requires constraint<Alias>
49 // All of these refer to a parent, so these are not duplicate definitions.
50 struct ChildOfEnclosing {
51 template <typename U>
52 friend void foo6()
53 requires constraint<T>
55 template <typename U>
56 friend void foo7()
57 requires constraint<decltype(variable)>
59 template <typename U>
60 friend void foo8(T parmvar)
61 requires constraint<decltype(parmvar)>
63 // This is NOT a duplicate since it itself is not a template.
64 friend void foo9()
65 requires true
68 template <typename T2>
69 struct TemplChildOfEnclosing {
70 template <typename U>
71 friend void foo10()
72 requires constraint<T>
77 // Doesn't meet either of the requirements in the above as they don't refer to
78 // an enclosing scope.
79 template <typename T>
80 struct Redefinition {
81 template <typename U>
82 friend void foo() // #REDEF
83 requires constraint<U>
86 struct ChildOfRedef {
87 template <typename U>
88 friend void foo2() // #REDEF2
89 requires constraint<U>
92 template <typename T2>
93 struct ChildOfRedef2 {
94 template <typename U>
95 friend void foo3() // #REDEF3
96 requires constraint<U>
101 void bar() {
102 NonTemplateFriend<int> S1;
103 NonTemplateFriend<float> S2;
104 TemplateFromEnclosing<int> S3;
105 TemplateFromEnclosing<int>::ChildOfEnclosing S3b;
106 TemplateFromEnclosing<float> S4;
107 TemplateFromEnclosing<float>::ChildOfEnclosing S4b;
108 Redefinition<int> S5;
109 Redefinition<float> S6;
110 // expected-error@#REDEF {{redefinition of 'foo'}}
111 // expected-note@-2{{in instantiation of template class }}
112 // expected-note@#REDEF {{previous definition is here}}
113 Redefinition<int>::ChildOfRedef S7;
114 Redefinition<float>::ChildOfRedef S8;
115 // expected-error@#REDEF2 {{redefinition of 'foo2'}}
116 // expected-note@-2{{in instantiation of member class }}
117 // expected-note@#REDEF2 {{previous definition is here}}
119 Redefinition<int>::ChildOfRedef2<int> S9;
120 Redefinition<float>::ChildOfRedef2<float> S10;
121 // expected-error@#REDEF3 {{redefinition of 'foo3'}}
122 // expected-note@-2{{in instantiation of template class }}
123 // expected-note@#REDEF3 {{previous definition is here}}
125 } // namespace temp_friend_9
127 namespace SameScopeRedefs {
128 template <typename T>
129 struct NonTemplateFriend {
130 friend void foo() // #NTF1
131 requires true
133 friend void foo() // #NTF2
134 requires true
138 template <typename T>
139 struct TemplateFromEnclosing {
140 template <typename U>
141 friend void foo() // #TFE1
142 requires constraint<T>
144 template <typename U>
145 friend void foo() // #TFE2
146 requires constraint<T>
149 // Same as above, but doesn't require an instantiation pair to cause.
150 template <typename T>
151 struct Redefinition {
152 template <typename U>
153 friend void foo() // #RD1
154 requires constraint<U>
156 template <typename U>
157 friend void foo() // #RD2
158 requires constraint<U>
161 void bar() {
162 NonTemplateFriend<int> S1;
163 // expected-error@#NTF2 {{redefinition of 'foo'}}
164 // expected-note@-2{{in instantiation of template class}}
165 // expected-note@#NTF1 {{previous definition is here}}
167 TemplateFromEnclosing<int> S2;
168 // expected-error@#TFE2 {{redefinition of 'foo'}}
169 // expected-note@-2{{in instantiation of template class}}
170 // expected-note@#TFE1 {{previous definition is here}}
172 Redefinition<int> S3;
173 // expected-error@#RD2 {{redefinition of 'foo'}}
174 // expected-note@-2{{in instantiation of template class}}
175 // expected-note@#RD1 {{previous definition is here}}
177 } // namespace SameScopeRedefs
179 namespace LibCXXOperatorRedef {
180 template <typename T, typename U> struct is_same {
181 static constexpr bool value = false;
183 template <typename T> struct is_same<T, T> {
184 static constexpr bool value = false;
187 template <typename T, typename U>
188 concept same_as = is_same<T, U>::value;
190 // An issue found from libcxx when trying to commit the deferred concepts patch.
191 // This caused an error of 'redefinition of funcN'.
192 template <class _Tp> struct __range_adaptor_closure {
193 template <typename _View, typename _Closure>
194 requires same_as<_Tp, _Closure>
195 friend constexpr decltype(auto) R1func1(_View &&__view,
196 _Closure &&__closure){};
197 template <typename _View, typename _Closure>
198 friend constexpr decltype(auto) R1func2(_View &&__view,
199 _Closure &&__closure)
200 requires same_as<_Tp, _Closure>
202 template <same_as<_Tp> _View, typename _Closure>
203 friend constexpr decltype(auto) R1func3(_View &&__view,
204 _Closure &&__closure){};
207 struct A : __range_adaptor_closure<A> {};
208 struct B : __range_adaptor_closure<B> {};
210 // These three fail because after the 1st pass of instantiation, they are still
211 // identical.
212 template <class _Tp> struct __range_adaptor_closure2 {
213 template <typename _View, typename _Closure>
214 requires same_as<_View, _Closure>
215 friend constexpr decltype(auto) R2func1(_View &&__view, // #FUNC1
216 _Closure &&__closure){};
217 template <typename _View, typename _Closure>
218 friend constexpr decltype(auto) R2func2(_View &&__view, // #FUNC2
219 _Closure &&__closure)
220 requires same_as<_View, _Closure>
222 template <typename _View, same_as<_View> _Closure>
223 friend constexpr decltype(auto) R2func3(_View &&__view, // #FUNC3
224 _Closure &&__closure){};
227 struct A2 : __range_adaptor_closure2<A2> {};
228 struct B2 : __range_adaptor_closure2<B2> {};
229 // expected-error@#FUNC1{{redefinition of 'R2func1'}}
230 // expected-note@-2{{in instantiation of template class}}
231 // expected-note@#FUNC1{{previous definition is here}}
232 // expected-error@#FUNC2{{redefinition of 'R2func2'}}
233 // expected-note@#FUNC2{{previous definition is here}}
234 // expected-error@#FUNC3{{redefinition of 'R2func3'}}
235 // expected-note@#FUNC3{{previous definition is here}}
237 // These three are fine, they all depend on the parent template parameter, so
238 // are different despite ::type not being valid.
239 template <class _Tp> struct __range_adaptor_closure3 {
240 template <typename _View, typename _Closure>
241 requires same_as<typename _Tp::type, _Closure>
242 friend constexpr decltype(auto) R3func1(_View &&__view,
243 _Closure &&__closure){};
244 template <typename _View, typename _Closure>
245 friend constexpr decltype(auto) R3func2(_View &&__view,
246 _Closure &&__closure)
247 requires same_as<typename _Tp::type, _Closure>
249 template <same_as<typename _Tp::type> _View, typename _Closure>
250 friend constexpr decltype(auto) R3func3(_View &&__view,
251 _Closure &&__closure){};
254 struct A3 : __range_adaptor_closure3<A3> {};
255 struct B3 : __range_adaptor_closure3<B3> {};
257 template <class _Tp> struct __range_adaptor_closure4 {
258 template <typename _View, typename _Closure>
259 requires same_as<_Tp, _View>
260 // expected-note@+1{{previous definition is here}}
261 void foo1(_View &&, _Closure &&) {}
262 template <typename _View, typename _Closure>
263 requires same_as<_Tp, _View>
264 // expected-error@+1{{class member cannot be redeclared}}
265 void foo1(_View &&, _Closure &&) {}
267 template <typename _View, typename _Closure>
268 // expected-note@+1{{previous definition is here}}
269 void foo2(_View &&, _Closure &&)
270 requires same_as<_Tp, _View>
272 template <typename _View, typename _Closure>
273 // expected-error@+1{{class member cannot be redeclared}}
274 void foo2(_View &&, _Closure &&)
275 requires same_as<_Tp, _View>
278 template <same_as<_Tp> _View, typename _Closure>
279 // expected-note@+1{{previous definition is here}}
280 void foo3(_View &&, _Closure &&) {}
281 template <same_as<_Tp> _View, typename _Closure>
282 // expected-error@+1{{class member cannot be redeclared}}
283 void foo3(_View &&, _Closure &&) {}
286 // Requires instantiation to fail, so no errors here.
287 template <class _Tp> struct __range_adaptor_closure5 {
288 template <same_as<_Tp> U>
289 friend void foo() {}
290 template <same_as<_Tp> U>
291 friend void foo() {}
294 template <class _Tp> struct __range_adaptor_closure6 {
295 template <same_as<_Tp> U>
296 friend void foo() {} // #RAC6FOO1
297 template <same_as<_Tp> U>
298 friend void foo() {} // #RAC6FOO2
300 struct A6 : __range_adaptor_closure6<A6> {};
301 // expected-error@#RAC6FOO2{{redefinition of 'foo'}}
302 // expected-note@-2{{in instantiation of template class}}
303 // expected-note@#RAC6FOO1{{previous definition is here}}
305 template <class T> struct S1 {
306 template <typename U>
307 friend void dupe() {} // #S1DUPE
309 template <typename U>
310 requires same_as<U, U>
311 friend void dupe2() {} // #S1DUPE2
313 template <class T> struct S2 {
314 template <typename U>
315 friend void dupe() {} // #S2DUPE
317 template <typename U>
318 requires same_as<U, U>
319 friend void dupe2() {} // #S2DUPE2
322 template <class T> struct S3 {
323 template <typename U>
324 requires same_as<T, U>
325 friend void dupe() {}
327 template <class T> struct S4 {
328 template <typename U>
329 requires same_as<T, U>
330 friend void dupe() {}
333 // Same as S3 and S4, but aren't instantiated with the same T.
334 template <class T> struct S5 {
335 template <typename U>
336 requires same_as<T, U>
337 friend void not_dupe() {}
339 template <class T> struct S6 {
340 template <typename U>
341 requires same_as<T, U>
342 friend void not_dupe() {}
345 template <class T> struct S7 {
346 void not_dupe()
347 requires same_as<T, T>
351 void useS() {
352 S1<int> s1;
353 S2<double> s2;
354 // expected-error@#S2DUPE{{redefinition}}
355 // expected-note@-2{{in instantiation of template class}}
356 // expected-note@#S1DUPE{{previous definition is here}}
357 // expected-error@#S2DUPE2{{redefinition}}
358 // expected-note@#S1DUPE2{{previous definition is here}}
360 // OK, they have different 'scopes'.
361 S3<int> s3;
362 S4<int> s4;
364 // OK, because only instantiated with different T.
365 S5<int> s5;
366 S6<double> s6;
368 S7<int> s7;
371 } // namespace LibCXXOperatorRedef
373 namespace NamedDeclRefs {
374 namespace my_std {
375 template<typename T, typename U>
376 concept Outer = true;
377 template<typename T>
378 using Inner = T;
380 template<typename T>
381 struct Proxy {
382 template<class U>
383 friend constexpr void RefOuter()
384 requires my_std::Outer<my_std::Inner<T>, my_std::Inner<U>>{}
385 template<class U>
386 friend constexpr void NoRefOuter() // #NOREFOUTER
387 requires my_std::Outer<my_std::Inner<U>, my_std::Inner<U>>{}
389 void use() {
390 Proxy<int> p;
391 Proxy<float> p2;
392 // expected-error@#NOREFOUTER {{redefinition of 'NoRefOuter'}}
393 // expected-note@-2{{in instantiation of template class}}
394 // expected-note@#NOREFOUTER{{previous definition is here}}
396 } // namespace NamedDeclRefs
398 namespace RefersToParentInConstraint {
399 // No diagnostic, these aren't duplicates.
400 template<typename T, typename U>
401 concept similar = true;
403 template <typename X>
404 struct S{
405 friend void f(similar<S> auto && self){}
406 friend void f2(similar<S<X>> auto && self){}
409 void use() {
410 S<int> x;
411 S<long> y;
413 } // namespace RefersToParentInConstraint
415 namespace NTTP {
416 struct Base{};
417 template<int N>
418 struct S : Base {
419 // N is from the parent template.
420 template<typename T>
421 friend int templ_func(Base&) requires(N > 0)
422 { return 10; }
425 template<typename T>
426 struct U : Base {
427 template<T N>
428 friend int templ_func(Base&) requires(N>0)
429 { return 10; }
432 void use() {
433 S<1> s1;
434 templ_func<float>(s1);
435 S<2> s2;
436 templ_func<float>(s2);
438 U<int> u1;
439 templ_func<1>(u1);
440 U<short> u2;
441 templ_func<1>(u2);