brintos

brintos / llvm-project-archived public Read only

0
0
Text · 15.1 KiB · 11287aa Raw
569 lines · cpp
1// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s2 3template <typename T>4concept constraint = false;5 6namespace temp_friend_9 {7// A non-template friend declaration with a requires-clause shall be a8// definition. ...Such a constrained friend function ... does not declare the9// same function or function template as a declaration in any other scope.10template <typename T>11struct NonTemplateFriend {12  friend void foo()13    requires true14  {}15 16  friend void baz() // expected-error {{non-template friend declaration with a requires clause must be a definition}}17    requires true;18};19 20struct TempP9NotShownIfFunctionWouldBeInvalidAnyway {21  friend void foo()22    requires true; // expected-error {{non-templated function cannot have a requires clause}}23};24 25// A friend function template with a constraint that depends on a template26// parameter from an enclosing template shall be a definition.  Such a ...27// function template declaration does not declare the same function or28// function template as a declaration in any other scope.29template <typename T>30struct TemplateFromEnclosing {31  template <typename U>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>;34 35  template <typename U>36  friend void foo()37    requires constraint<T>38  {}39 40  T variable;41  template <typename U>42  friend void foo2()43    requires constraint<decltype(variable)>44  {}45 46  template <typename U>47  friend void foo3(T parmvar)48    requires constraint<decltype(parmvar)>49  {}50 51  template <typename U>52  friend void foo4()53    requires requires(T &req) { (void)req; }54  {}55 56  using Alias = T;57  template <typename U>58  friend void foo5()59    requires constraint<Alias>60  {}61 62  // All of these refer to a parent, so these are not duplicate definitions.63  struct ChildOfEnclosing {64    template <typename U>65    friend void foo6()66      requires constraint<T>67    {}68    template <typename U>69    friend void foo7()70      requires constraint<decltype(variable)>71    {}72    template <typename U>73    friend void foo8(T parmvar)74      requires constraint<decltype(parmvar)>75    {}76    // This is NOT a duplicate since it itself is not a template.77    friend void foo9()78      requires true79    {}80  };81  template <typename T2>82  struct TemplChildOfEnclosing {83    template <typename U>84    friend void foo10()85      requires constraint<T>86    {}87  };88};89 90// Doesn't meet either of the requirements in the above as they don't refer to91// an enclosing scope.92template <typename T>93struct Redefinition {94  template <typename U>95  friend void foo() // #REDEF96    requires constraint<U>97  {}98 99  struct ChildOfRedef {100    template <typename U>101    friend void foo2() // #REDEF2102      requires constraint<U>103    {}104  };105  template <typename T2>106  struct ChildOfRedef2 {107    template <typename U>108    friend void foo3() // #REDEF3109      requires constraint<U>110    {}111  };112};113 114void bar() {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}}131 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}}137}138} // namespace temp_friend_9139 140namespace SameScopeRedefs {141template <typename T>142struct NonTemplateFriend {143  friend void foo() // #NTF1144    requires true145  {}146  friend void foo() // #NTF2147    requires true148  {}149};150 151template <typename T>152struct TemplateFromEnclosing {153  template <typename U>154  friend void foo() // #TFE1155    requires constraint<T>156  {}157  template <typename U>158  friend void foo() // #TFE2159    requires constraint<T>160  {}161};162// Same as above, but doesn't require an instantiation pair to cause.163template <typename T>164struct Redefinition {165  template <typename U>166  friend void foo() // #RD1167    requires constraint<U>168  {}169  template <typename U>170  friend void foo() // #RD2171    requires constraint<U>172  {}173};174void bar() {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}}179 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}}184 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}}189}190} // namespace SameScopeRedefs191 192namespace LibCXXOperatorRedef {193template <typename T, typename U> struct is_same {194  static constexpr bool value = false;195};196template <typename T> struct is_same<T, T> {197  static constexpr bool value = false;198};199 200template <typename T, typename U>201concept same_as = is_same<T, U>::value;202 203// An issue found from libcxx when trying to commit the deferred concepts patch.204// This caused an error of 'redefinition of funcN'.205template <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>214  {};215  template <same_as<_Tp> _View, typename _Closure>216  friend constexpr decltype(auto) R1func3(_View &&__view,217                                          _Closure &&__closure){};218};219 220struct A : __range_adaptor_closure<A> {};221struct B : __range_adaptor_closure<B> {};222 223// These three fail because after the 1st pass of instantiation, they are still224// identical.225template <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, // #FUNC1229                                          _Closure &&__closure){};230  template <typename _View, typename _Closure>231  friend constexpr decltype(auto) R2func2(_View &&__view, // #FUNC2232                                          _Closure &&__closure)233    requires same_as<_View, _Closure>234  {};235  template <typename _View, same_as<_View> _Closure>236  friend constexpr decltype(auto) R2func3(_View &&__view, // #FUNC3237                                          _Closure &&__closure){};238};239 240struct A2 : __range_adaptor_closure2<A2> {};241struct 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}}249 250// These three are fine, they all depend on the parent template parameter, so251// are different despite ::type not being valid.252template <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>261  {};262  template <same_as<typename _Tp::type> _View, typename _Closure>263  friend constexpr decltype(auto) R3func3(_View &&__view,264                                          _Closure &&__closure){};265};266 267struct A3 : __range_adaptor_closure3<A3> {};268struct B3 : __range_adaptor_closure3<B3> {};269 270template <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 &&) {}279 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>284  {}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>289  {}290 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 &&) {}297};298 299// Requires instantiation to fail, so no errors here.300template <class _Tp> struct __range_adaptor_closure5 {301  template <same_as<_Tp> U>302  friend void foo() {}303  template <same_as<_Tp> U>304  friend void foo() {}305};306 307template <class _Tp> struct __range_adaptor_closure6 {308  template <same_as<_Tp> U>309  friend void foo() {} // #RAC6FOO1310  template <same_as<_Tp> U>311  friend void foo() {} // #RAC6FOO2312};313struct 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}}317 318template <class T> struct S1 {319  template <typename U>320  friend void dupe() {} // #S1DUPE321 322  template <typename U>323    requires same_as<U, U>324  friend void dupe2() {} // #S1DUPE2325};326template <class T> struct S2 {327  template <typename U>328  friend void dupe() {} // #S2DUPE329 330  template <typename U>331    requires same_as<U, U>332  friend void dupe2() {} // #S2DUPE2333};334 335template <class T> struct S3 {336  template <typename U>337    requires same_as<T, U>338  friend void dupe() {}339};340template <class T> struct S4 {341  template <typename U>342    requires same_as<T, U>343  friend void dupe() {}344};345 346// Same as S3 and S4, but aren't instantiated with the same T.347template <class T> struct S5 {348  template <typename U>349    requires same_as<T, U>350  friend void not_dupe() {}351};352template <class T> struct S6 {353  template <typename U>354    requires same_as<T, U>355  friend void not_dupe() {}356};357 358template <class T> struct S7 {359  void not_dupe()360    requires same_as<T, T>361  {}362};363 364void useS() {365  S1<int> s1;366  S2<double> s2;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}}372 373  // OK, they have different 'scopes'.374  S3<int> s3;375  S4<int> s4;376 377  // OK, because only instantiated with different T.378  S5<int> s5;379  S6<double> s6;380 381  S7<int> s7;382}383 384} // namespace LibCXXOperatorRedef385 386namespace NamedDeclRefs {387  namespace my_std {388    template<typename T, typename U>389      concept Outer = true;390    template<typename T>391      using Inner = T;392  }393  template<typename T>394    struct Proxy {395      template<class U>396        friend constexpr void RefOuter()397        requires my_std::Outer<my_std::Inner<T>, my_std::Inner<U>>{}398      template<class U>399        friend constexpr void NoRefOuter() // #NOREFOUTER400        requires my_std::Outer<my_std::Inner<U>, my_std::Inner<U>>{}401    };402  void use() {403    Proxy<int> p;404    Proxy<float> p2;405    // expected-error@#NOREFOUTER {{redefinition of 'NoRefOuter'}}406    // expected-note@-2{{in instantiation of template class}}407    // expected-note@#NOREFOUTER{{previous definition is here}}408  }409} // namespace NamedDeclRefs410 411namespace RefersToParentInConstraint {412  // No diagnostic, these aren't duplicates.413  template<typename T, typename U>414  concept similar = true;415 416  template <typename X>417  struct S{418    friend void f(similar<S> auto && self){}419    friend void f2(similar<S<X>> auto && self){}420  };421 422  void use() {423    S<int> x;424    S<long> y;425  }426} // namespace RefersToParentInConstraint427 428namespace NTTP {429  struct Base{};430  template<int N>431  struct S : Base {432    // N is from the parent template.433    template<typename T>434      friend int templ_func(Base&) requires(N > 0)435      { return 10; }436  };437 438  template<typename T>439  struct U : Base {440    template<T N>441      friend int templ_func(Base&) requires(N>0)442      { return 10; }443  };444 445  void use() {446    S<1> s1;447    templ_func<float>(s1);448    S<2> s2;449    templ_func<float>(s2);450 451    U<int> u1;452    templ_func<1>(u1);453    U<short> u2;454    templ_func<1>(u2);455  }456}457 458 459namespace FriendOfFriend {460 461template <typename>462concept Concept = true;463 464template <Concept> class FriendOfBar;465 466template <Concept> class Bar {467  template <Concept> friend class FriendOfBar;468};469 470Bar<void> BarInstance;471 472namespace internal {473void FriendOfFoo(FriendOfBar<void>);474}475 476template <Concept> class Foo {477  friend void internal::FriendOfFoo(FriendOfBar<void>);478};479 480} // namespace FriendOfFriend481 482namespace GH86769 {483 484template <typename T>485concept X = true;486 487template <X T> struct Y {488  Y(T) {}489  template <X U> friend struct Y;490  template <X U> friend struct Y;491  template <X U> friend struct Y;492};493 494template <class T>495struct Z {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 class498  // template declaration.499  template <X U = void> friend struct Y;500};501 502template struct Y<int>;503template struct Z<int>;504Y y(1);505 506}507 508namespace GH98258 {509 510struct S {511  template <typename U>512  friend void f() requires requires { []<typename V>(V){}; } {513    return;514  }515 516  template <typename U>517  friend void f2() requires requires { [](auto){}; } {518    return;519  }520 521  template <typename U>522  friend void f3() requires requires { []<int X>(){ return X; }; } {523    return;524  }525};526 527}528 529namespace GH78101 {530 531template <typename T, int i>532concept True = true;533 534template <typename T, int I> struct Template {535  static constexpr int i = I;536 537  friend constexpr auto operator+(True<i> auto f) { return i; }538};539 540template <int I> struct Template<float, I> {541  static constexpr int i = I;542 543  friend constexpr auto operator+(True<i> auto f) { return i; }544};545 546Template<void, 4> f{};547 548static_assert(+Template<float, 5>{} == 5);549 550} // namespace GH78101551 552namespace GH156225 {553 554struct Test {555  template <class T>556  friend constexpr bool foo()557    requires([] {558      bool flags[1];559      for (bool x : flags)560        return false;561      return true;562    }())563  {564    return {};565  }566};567 568}569