1 // RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s
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.
10 struct NonTemplateFriend
{
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.
21 struct TemplateFromEnclosing
{
24 requires constraint
<T
>
30 requires constraint
<decltype(variable
)>
34 friend void foo3(T parmvar
)
35 requires constraint
<decltype(parmvar
)>
40 requires
requires(T
&req
) { (void)req
; }
46 requires constraint
<Alias
>
49 // All of these refer to a parent, so these are not duplicate definitions.
50 struct ChildOfEnclosing
{
53 requires constraint
<T
>
57 requires constraint
<decltype(variable
)>
60 friend void foo8(T parmvar
)
61 requires constraint
<decltype(parmvar
)>
63 // This is NOT a duplicate since it itself is not a template.
68 template <typename T2
>
69 struct TemplChildOfEnclosing
{
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.
82 friend void foo() // #REDEF
83 requires constraint
<U
>
88 friend void foo2() // #REDEF2
89 requires constraint
<U
>
92 template <typename T2
>
93 struct ChildOfRedef2
{
95 friend void foo3() // #REDEF3
96 requires constraint
<U
>
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
133 friend void foo() // #NTF2
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
>
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
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
>
290 template <same_as
<_Tp
> U
>
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
{
347 requires same_as
<T
, T
>
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'.
364 // OK, because only instantiated with different T.
371 } // namespace LibCXXOperatorRedef
373 namespace NamedDeclRefs
{
375 template<typename T
, typename U
>
376 concept Outer
= true;
383 friend constexpr void RefOuter()
384 requires
my_std::Outer
<my_std::Inner
<T
>, my_std::Inner
<U
>>{}
386 friend constexpr void NoRefOuter() // #NOREFOUTER
387 requires
my_std::Outer
<my_std::Inner
<U
>, my_std::Inner
<U
>>{}
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
>
405 friend void f(similar
<S
> auto && self
){}
406 friend void f2(similar
<S
<X
>> auto && self
){}
413 } // namespace RefersToParentInConstraint
419 // N is from the parent template.
421 friend int templ_func(Base
&) requires(N
> 0)
428 friend int templ_func(Base
&) requires(N
>0)
434 templ_func
<float>(s1
);
436 templ_func
<float>(s2
);