1 // RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s
4 concept constraint
= false;
6 namespace temp_friend_9
{
7 // A non-template friend declaration with a requires-clause shall be a
8 // definition. ...Such a constrained friend function ... does not declare the
9 // same function or function template as a declaration in any other scope.
11 struct NonTemplateFriend
{
16 friend void baz() // expected-error {{non-template friend declaration with a requires clause must be a definition}}
20 struct TempP9NotShownIfFunctionWouldBeInvalidAnyway
{
22 requires
true; // expected-error {{non-templated function cannot have a requires clause}}
25 // A friend function template with a constraint that depends on a template
26 // parameter from an enclosing template shall be a definition. Such a ...
27 // function template declaration does not declare the same function or
28 // function template as a declaration in any other scope.
30 struct TemplateFromEnclosing
{
32 friend void bar2() // expected-error {{friend declaration with a constraint that depends on an enclosing template parameter must be a definition}}
33 requires constraint
<T
>;
37 requires constraint
<T
>
43 requires constraint
<decltype(variable
)>
47 friend void foo3(T parmvar
)
48 requires constraint
<decltype(parmvar
)>
53 requires
requires(T
&req
) { (void)req
; }
59 requires constraint
<Alias
>
62 // All of these refer to a parent, so these are not duplicate definitions.
63 struct ChildOfEnclosing
{
66 requires constraint
<T
>
70 requires constraint
<decltype(variable
)>
73 friend void foo8(T parmvar
)
74 requires constraint
<decltype(parmvar
)>
76 // This is NOT a duplicate since it itself is not a template.
81 template <typename T2
>
82 struct TemplChildOfEnclosing
{
85 requires constraint
<T
>
90 // Doesn't meet either of the requirements in the above as they don't refer to
91 // an enclosing scope.
95 friend void foo() // #REDEF
96 requires constraint
<U
>
100 template <typename U
>
101 friend void foo2() // #REDEF2
102 requires constraint
<U
>
105 template <typename T2
>
106 struct ChildOfRedef2
{
107 template <typename U
>
108 friend void foo3() // #REDEF3
109 requires constraint
<U
>
115 NonTemplateFriend
<int> S1
;
116 NonTemplateFriend
<float> S2
;
117 TemplateFromEnclosing
<int> S3
;
118 TemplateFromEnclosing
<int>::ChildOfEnclosing S3b
;
119 TemplateFromEnclosing
<float> S4
;
120 TemplateFromEnclosing
<float>::ChildOfEnclosing S4b
;
121 Redefinition
<int> S5
;
122 Redefinition
<float> S6
;
123 // expected-error@#REDEF {{redefinition of 'foo'}}
124 // expected-note@-2{{in instantiation of template class }}
125 // expected-note@#REDEF {{previous definition is here}}
126 Redefinition
<int>::ChildOfRedef S7
;
127 Redefinition
<float>::ChildOfRedef S8
;
128 // expected-error@#REDEF2 {{redefinition of 'foo2'}}
129 // expected-note@-2{{in instantiation of member class }}
130 // expected-note@#REDEF2 {{previous definition is here}}
132 Redefinition
<int>::ChildOfRedef2
<int> S9
;
133 Redefinition
<float>::ChildOfRedef2
<float> S10
;
134 // expected-error@#REDEF3 {{redefinition of 'foo3'}}
135 // expected-note@-2{{in instantiation of template class }}
136 // expected-note@#REDEF3 {{previous definition is here}}
138 } // namespace temp_friend_9
140 namespace SameScopeRedefs
{
141 template <typename T
>
142 struct NonTemplateFriend
{
143 friend void foo() // #NTF1
146 friend void foo() // #NTF2
151 template <typename T
>
152 struct TemplateFromEnclosing
{
153 template <typename U
>
154 friend void foo() // #TFE1
155 requires constraint
<T
>
157 template <typename U
>
158 friend void foo() // #TFE2
159 requires constraint
<T
>
162 // Same as above, but doesn't require an instantiation pair to cause.
163 template <typename T
>
164 struct Redefinition
{
165 template <typename U
>
166 friend void foo() // #RD1
167 requires constraint
<U
>
169 template <typename U
>
170 friend void foo() // #RD2
171 requires constraint
<U
>
175 NonTemplateFriend
<int> S1
;
176 // expected-error@#NTF2 {{redefinition of 'foo'}}
177 // expected-note@-2{{in instantiation of template class}}
178 // expected-note@#NTF1 {{previous definition is here}}
180 TemplateFromEnclosing
<int> S2
;
181 // expected-error@#TFE2 {{redefinition of 'foo'}}
182 // expected-note@-2{{in instantiation of template class}}
183 // expected-note@#TFE1 {{previous definition is here}}
185 Redefinition
<int> S3
;
186 // expected-error@#RD2 {{redefinition of 'foo'}}
187 // expected-note@-2{{in instantiation of template class}}
188 // expected-note@#RD1 {{previous definition is here}}
190 } // namespace SameScopeRedefs
192 namespace LibCXXOperatorRedef
{
193 template <typename T
, typename U
> struct is_same
{
194 static constexpr bool value
= false;
196 template <typename T
> struct is_same
<T
, T
> {
197 static constexpr bool value
= false;
200 template <typename T
, typename U
>
201 concept same_as
= is_same
<T
, U
>::value
;
203 // An issue found from libcxx when trying to commit the deferred concepts patch.
204 // This caused an error of 'redefinition of funcN'.
205 template <class _Tp
> struct __range_adaptor_closure
{
206 template <typename _View
, typename _Closure
>
207 requires same_as
<_Tp
, _Closure
>
208 friend constexpr decltype(auto) R1func1(_View
&&__view
,
209 _Closure
&&__closure
){};
210 template <typename _View
, typename _Closure
>
211 friend constexpr decltype(auto) R1func2(_View
&&__view
,
212 _Closure
&&__closure
)
213 requires same_as
<_Tp
, _Closure
>
215 template <same_as
<_Tp
> _View
, typename _Closure
>
216 friend constexpr decltype(auto) R1func3(_View
&&__view
,
217 _Closure
&&__closure
){};
220 struct A
: __range_adaptor_closure
<A
> {};
221 struct B
: __range_adaptor_closure
<B
> {};
223 // These three fail because after the 1st pass of instantiation, they are still
225 template <class _Tp
> struct __range_adaptor_closure2
{
226 template <typename _View
, typename _Closure
>
227 requires same_as
<_View
, _Closure
>
228 friend constexpr decltype(auto) R2func1(_View
&&__view
, // #FUNC1
229 _Closure
&&__closure
){};
230 template <typename _View
, typename _Closure
>
231 friend constexpr decltype(auto) R2func2(_View
&&__view
, // #FUNC2
232 _Closure
&&__closure
)
233 requires same_as
<_View
, _Closure
>
235 template <typename _View
, same_as
<_View
> _Closure
>
236 friend constexpr decltype(auto) R2func3(_View
&&__view
, // #FUNC3
237 _Closure
&&__closure
){};
240 struct A2
: __range_adaptor_closure2
<A2
> {};
241 struct B2
: __range_adaptor_closure2
<B2
> {};
242 // expected-error@#FUNC1{{redefinition of 'R2func1'}}
243 // expected-note@-2{{in instantiation of template class}}
244 // expected-note@#FUNC1{{previous definition is here}}
245 // expected-error@#FUNC2{{redefinition of 'R2func2'}}
246 // expected-note@#FUNC2{{previous definition is here}}
247 // expected-error@#FUNC3{{redefinition of 'R2func3'}}
248 // expected-note@#FUNC3{{previous definition is here}}
250 // These three are fine, they all depend on the parent template parameter, so
251 // are different despite ::type not being valid.
252 template <class _Tp
> struct __range_adaptor_closure3
{
253 template <typename _View
, typename _Closure
>
254 requires same_as
<typename
_Tp::type
, _Closure
>
255 friend constexpr decltype(auto) R3func1(_View
&&__view
,
256 _Closure
&&__closure
){};
257 template <typename _View
, typename _Closure
>
258 friend constexpr decltype(auto) R3func2(_View
&&__view
,
259 _Closure
&&__closure
)
260 requires same_as
<typename
_Tp::type
, _Closure
>
262 template <same_as
<typename
_Tp::type
> _View
, typename _Closure
>
263 friend constexpr decltype(auto) R3func3(_View
&&__view
,
264 _Closure
&&__closure
){};
267 struct A3
: __range_adaptor_closure3
<A3
> {};
268 struct B3
: __range_adaptor_closure3
<B3
> {};
270 template <class _Tp
> struct __range_adaptor_closure4
{
271 template <typename _View
, typename _Closure
>
272 requires same_as
<_Tp
, _View
>
273 // expected-note@+1{{previous definition is here}}
274 void foo1(_View
&&, _Closure
&&) {}
275 template <typename _View
, typename _Closure
>
276 requires same_as
<_Tp
, _View
>
277 // expected-error@+1{{class member cannot be redeclared}}
278 void foo1(_View
&&, _Closure
&&) {}
280 template <typename _View
, typename _Closure
>
281 // expected-note@+1{{previous definition is here}}
282 void foo2(_View
&&, _Closure
&&)
283 requires same_as
<_Tp
, _View
>
285 template <typename _View
, typename _Closure
>
286 // expected-error@+1{{class member cannot be redeclared}}
287 void foo2(_View
&&, _Closure
&&)
288 requires same_as
<_Tp
, _View
>
291 template <same_as
<_Tp
> _View
, typename _Closure
>
292 // expected-note@+1{{previous definition is here}}
293 void foo3(_View
&&, _Closure
&&) {}
294 template <same_as
<_Tp
> _View
, typename _Closure
>
295 // expected-error@+1{{class member cannot be redeclared}}
296 void foo3(_View
&&, _Closure
&&) {}
299 // Requires instantiation to fail, so no errors here.
300 template <class _Tp
> struct __range_adaptor_closure5
{
301 template <same_as
<_Tp
> U
>
303 template <same_as
<_Tp
> U
>
307 template <class _Tp
> struct __range_adaptor_closure6
{
308 template <same_as
<_Tp
> U
>
309 friend void foo() {} // #RAC6FOO1
310 template <same_as
<_Tp
> U
>
311 friend void foo() {} // #RAC6FOO2
313 struct A6
: __range_adaptor_closure6
<A6
> {};
314 // expected-error@#RAC6FOO2{{redefinition of 'foo'}}
315 // expected-note@-2{{in instantiation of template class}}
316 // expected-note@#RAC6FOO1{{previous definition is here}}
318 template <class T
> struct S1
{
319 template <typename U
>
320 friend void dupe() {} // #S1DUPE
322 template <typename U
>
323 requires same_as
<U
, U
>
324 friend void dupe2() {} // #S1DUPE2
326 template <class T
> struct S2
{
327 template <typename U
>
328 friend void dupe() {} // #S2DUPE
330 template <typename U
>
331 requires same_as
<U
, U
>
332 friend void dupe2() {} // #S2DUPE2
335 template <class T
> struct S3
{
336 template <typename U
>
337 requires same_as
<T
, U
>
338 friend void dupe() {}
340 template <class T
> struct S4
{
341 template <typename U
>
342 requires same_as
<T
, U
>
343 friend void dupe() {}
346 // Same as S3 and S4, but aren't instantiated with the same T.
347 template <class T
> struct S5
{
348 template <typename U
>
349 requires same_as
<T
, U
>
350 friend void not_dupe() {}
352 template <class T
> struct S6
{
353 template <typename U
>
354 requires same_as
<T
, U
>
355 friend void not_dupe() {}
358 template <class T
> struct S7
{
360 requires same_as
<T
, T
>
367 // expected-error@#S2DUPE{{redefinition}}
368 // expected-note@-2{{in instantiation of template class}}
369 // expected-note@#S1DUPE{{previous definition is here}}
370 // expected-error@#S2DUPE2{{redefinition}}
371 // expected-note@#S1DUPE2{{previous definition is here}}
373 // OK, they have different 'scopes'.
377 // OK, because only instantiated with different T.
384 } // namespace LibCXXOperatorRedef
386 namespace NamedDeclRefs
{
388 template<typename T
, typename U
>
389 concept Outer
= true;
396 friend constexpr void RefOuter()
397 requires
my_std::Outer
<my_std::Inner
<T
>, my_std::Inner
<U
>>{}
399 friend constexpr void NoRefOuter() // #NOREFOUTER
400 requires
my_std::Outer
<my_std::Inner
<U
>, my_std::Inner
<U
>>{}
405 // expected-error@#NOREFOUTER {{redefinition of 'NoRefOuter'}}
406 // expected-note@-2{{in instantiation of template class}}
407 // expected-note@#NOREFOUTER{{previous definition is here}}
409 } // namespace NamedDeclRefs
411 namespace RefersToParentInConstraint
{
412 // No diagnostic, these aren't duplicates.
413 template<typename T
, typename U
>
414 concept similar
= true;
416 template <typename X
>
418 friend void f(similar
<S
> auto && self
){}
419 friend void f2(similar
<S
<X
>> auto && self
){}
426 } // namespace RefersToParentInConstraint
432 // N is from the parent template.
434 friend int templ_func(Base
&) requires(N
> 0)
441 friend int templ_func(Base
&) requires(N
>0)
447 templ_func
<float>(s1
);
449 templ_func
<float>(s2
);
459 namespace FriendOfFriend
{
462 concept Concept
= true;
464 template <Concept
> class FriendOfBar
;
466 template <Concept
> class Bar
{
467 template <Concept
> friend class FriendOfBar
;
470 Bar
<void> BarInstance
;
473 void FriendOfFoo(FriendOfBar
<void>);
476 template <Concept
> class Foo
{
477 friend void internal::FriendOfFoo(FriendOfBar
<void>);
480 } // namespace FriendOfFriend
484 template <typename T
>
487 template <X T
> struct Y
{
489 template <X U
> friend struct Y
;
490 template <X U
> friend struct Y
;
491 template <X U
> friend struct Y
;
496 // FIXME: This is ill-formed per C++11 N3337 [temp.param]p12:
497 // A default template argument shall not be specified in a friend class
498 // template declaration.
499 template <X U
= void> friend struct Y
;
502 template struct Y
<int>;
503 template struct Z
<int>;
511 template <typename U
>
512 friend void f() requires requires
{ []<typename V
>(V
){}; } {
516 template <typename U
>
517 friend void f2() requires requires
{ [](auto){}; } {
521 template <typename U
>
522 friend void f3() requires requires
{ []<int X
>(){ return X
; }; } {
531 template <typename T
, int i
>
534 template <typename T
, int I
> struct Template
{
535 static constexpr int i
= I
;
537 friend constexpr auto operator+(True
<i
> auto f
) { return i
; }
540 template <int I
> struct Template
<float, I
> {
541 static constexpr int i
= I
;
543 friend constexpr auto operator+(True
<i
> auto f
) { return i
; }
546 Template
<void, 4> f
{};
548 static_assert(+Template
<float, 5>{} == 5);
550 } // namespace GH78101