896 lines · cpp
1// RUN: %clang_cc1 -std=c++20 -Wno-c++26-extensions -verify %s2// RUN: %clang_cc1 -std=c++2c -Wno-c++26-extensions -verify %s3 4 5static constexpr int PRIMARY = 0;6static constexpr int SPECIALIZATION_CONCEPT = 1;7static constexpr int SPECIALIZATION_REQUIRES = 2;8 9template <class T>10concept Concept = (sizeof(T) >= 2 * sizeof(int));11 12struct XY {13 int x;14 int y;15};16 17namespace members {18 19template <class T, class U> struct S {20 static constexpr int primary();21};22 23template <class T, class U> constexpr int S<T, U>::primary() {24 return PRIMARY;25};26 27template <Concept C, class U> struct S<C, U> {28 static constexpr int specialization();29};30 31template <class T, class U>32 requires(sizeof(T) == sizeof(int))33struct S<T, U> {34 static constexpr int specialization();35};36 37template <Concept C, class U> constexpr int S<C, U>::specialization() {38 return SPECIALIZATION_CONCEPT;39}40 41template <class T, class U>42 requires(sizeof(T) == sizeof(int))43constexpr int S<T, U>::specialization() {44 return SPECIALIZATION_REQUIRES;45}46 47static_assert(S<char, double>::primary() == PRIMARY);48static_assert(S<XY, double>::specialization() == SPECIALIZATION_CONCEPT);49static_assert(S<int, double>::specialization() == SPECIALIZATION_REQUIRES);50 51} // namespace members52 53namespace enumerations {54 55template <class T, class U> struct S {56 enum class E : int;57};58 59template <class T, class U> enum class S<T, U>::E { Value = PRIMARY };60 61template <Concept C, class U> struct S<C, U> {62 enum class E : int;63};64 65template <Concept C, class U>66enum class S<C, U>::E {67 Value = SPECIALIZATION_CONCEPT68};69 70template <class T, class U>71 requires(sizeof(T) == sizeof(int))72struct S<T, U> {73 enum class E : int;74};75 76template <class T, class U>77 requires(sizeof(T) == sizeof(int))78enum class S<T, U>::E {79 Value = SPECIALIZATION_REQUIRES80};81 82static_assert(static_cast<int>(S<char, double>::E::Value) == PRIMARY);83static_assert(static_cast<int>(S<XY, double>::E::Value) ==84 SPECIALIZATION_CONCEPT);85static_assert(static_cast<int>(S<int, double>::E::Value) ==86 SPECIALIZATION_REQUIRES);87 88} // namespace enumerations89 90namespace multiple_template_parameter_lists {91 92template <class Outer>93struct S {94 template <class Inner>95 static constexpr int primary(Inner);96};97 98template <class Outer>99template <class Inner>100constexpr int S<Outer>::primary(Inner) {101 return PRIMARY;102};103 104template <Concept Outer>105struct S<Outer> {106 template <class Inner>107 static constexpr int specialization(Inner);108};109 110template <Concept Outer>111template <class Inner>112constexpr int S<Outer>::specialization(Inner) { return SPECIALIZATION_CONCEPT; }113 114template <class Outer>115 requires(sizeof(Outer) == sizeof(int))116struct S<Outer> {117 template <class Inner>118 static constexpr int specialization(Inner);119};120 121template <class Outer>122 requires(sizeof(Outer) == sizeof(int))123template <class Inner>124constexpr int S<Outer>::specialization(Inner) { return SPECIALIZATION_REQUIRES; }125 126static_assert(S<char>::primary("str") == PRIMARY);127static_assert(S<XY>::specialization("str") == SPECIALIZATION_CONCEPT);128static_assert(S<int>::specialization("str") == SPECIALIZATION_REQUIRES);129 130} // namespace multiple_template_parameter_lists131 132static constexpr int CONSTRAINED_METHOD_1 = 1;133static constexpr int CONSTRAINED_METHOD_2 = 2;134 135namespace constrained_members {136 137template <int>138struct S {139 template <Concept C>140 static constexpr int constrained_method();141};142 143template <>144template <Concept C>145constexpr int S<1>::constrained_method() { return CONSTRAINED_METHOD_1; }146 147template <>148template <Concept C>149constexpr int S<2>::constrained_method() { return CONSTRAINED_METHOD_2; }150 151static_assert(S<1>::constrained_method<XY>() == CONSTRAINED_METHOD_1);152static_assert(S<2>::constrained_method<XY>() == CONSTRAINED_METHOD_2);153 154 155template <class T1, class T2>156concept ConceptT1T2 = true;157 158template<typename T3>159struct S12 {160 template<ConceptT1T2<T3> T4>161 static constexpr int constrained_method();162};163 164template<>165template<ConceptT1T2<int> T5>166constexpr int S12<int>::constrained_method() { return CONSTRAINED_METHOD_1; }167 168template<>169template<ConceptT1T2<double> T5>170constexpr int S12<double>::constrained_method() { return CONSTRAINED_METHOD_2; }171 172static_assert(S12<int>::constrained_method<XY>() == CONSTRAINED_METHOD_1);173static_assert(S12<double>::constrained_method<XY>() == CONSTRAINED_METHOD_2);174 175} // namespace constrained members176 177namespace constrained_members_of_nested_types {178 179template <int>180struct S {181 struct Inner0 {182 struct Inner1 {183 template <Concept C>184 static constexpr int constrained_method();185 };186 };187};188 189template <>190template <Concept C>191constexpr int S<1>::Inner0::Inner1::constrained_method() { return CONSTRAINED_METHOD_1; }192 193template <>194template <Concept C>195constexpr int S<2>::Inner0::Inner1::constrained_method() { return CONSTRAINED_METHOD_2; }196 197static_assert(S<1>::Inner0::Inner1::constrained_method<XY>() == CONSTRAINED_METHOD_1);198static_assert(S<2>::Inner0::Inner1::constrained_method<XY>() == CONSTRAINED_METHOD_2);199 200 201template <class T1, class T2>202concept ConceptT1T2 = true;203 204template<typename T3>205struct S12 {206 struct Inner0 {207 struct Inner1 {208 template<ConceptT1T2<T3> T4>209 static constexpr int constrained_method();210 };211 };212};213 214template<>215template<ConceptT1T2<int> T5>216constexpr int S12<int>::Inner0::Inner1::constrained_method() { return CONSTRAINED_METHOD_1; }217 218template<>219template<ConceptT1T2<double> T5>220constexpr int S12<double>::Inner0::Inner1::constrained_method() { return CONSTRAINED_METHOD_2; }221 222static_assert(S12<int>::Inner0::Inner1::constrained_method<XY>() == CONSTRAINED_METHOD_1);223static_assert(S12<double>::Inner0::Inner1::constrained_method<XY>() == CONSTRAINED_METHOD_2);224 225} // namespace constrained_members_of_nested_types226 227namespace constrained_member_sfinae {228 229template<int N> struct S {230 template<class T>231 static constexpr int constrained_method() requires (sizeof(int[N * 1073741824 + 4]) == 16) { // expected-warning {{variable length arrays in C++ are a Clang extension}} \232 expected-note {{value 4294967296 is outside the range of representable values of type 'int'}} \233 expected-note {{while calculating associated constraint of template 'constrained_method' here}}234 return CONSTRAINED_METHOD_1;235 }236 237 template<class T>238 static constexpr int constrained_method() requires (sizeof(int[N]) == 16);239};240 241template<>242template<typename T>243constexpr int S<4>::constrained_method() requires (sizeof(int[4]) == 16) {244 return CONSTRAINED_METHOD_2;245}246 247// Verify that there is no amiguity in this case.248static_assert(S<4>::constrained_method<double>() == CONSTRAINED_METHOD_2);249 250} // namespace constrained_member_sfinae251 252namespace requires_expression_references_members {253 254void accept1(int x);255void accept2(XY xy);256 257template <class T> struct S {258 T Field = T();259 260 constexpr int constrained_method()261 requires requires { accept1(Field); };262 263 constexpr int constrained_method()264 requires requires { accept2(Field); };265};266 267template <class T>268constexpr int S<T>::constrained_method()269 requires requires { accept1(Field); } {270 return CONSTRAINED_METHOD_1;271}272 273template <class T>274constexpr int S<T>::constrained_method()275 requires requires { accept2(Field); } {276 return CONSTRAINED_METHOD_2;277}278 279static_assert(S<int>().constrained_method() == CONSTRAINED_METHOD_1);280static_assert(S<XY>().constrained_method() == CONSTRAINED_METHOD_2);281 282} // namespace requires_expression_references_members283 284namespace GH60231 {285 286template<typename T0> concept C = true;287 288template <typename T1>289struct S {290 template <typename F1> requires C<S<T1>>291 void foo1(F1 f);292 293 template <typename F2>294 void foo2(F2 f) requires C<S<T1>>;295 296 template <typename F3> requires C<F3>297 void foo3(F3 f);298};299 300template <typename T2>301template <typename F4> requires C<S<T2>>302void S<T2>::foo1(F4 f) {}303 304template <typename T3>305template <typename F5>306void S<T3>::foo2(F5 f) requires C<S<T3>> {}307 308template <typename T4>309template <typename F6> requires C<F6>310void S<T4>::foo3(F6 f) {}311 312} // namespace GH60231313 314namespace GH62003 {315 316template <typename T0> concept Concept = true;317 318template <class T1>319struct S1 {320 template <Concept C1>321 static constexpr int foo();322};323template <class T2>324template <Concept C2>325constexpr int S1<T2>::foo() { return 1; }326 327template <Concept C3>328struct S2 {329 template <class T3>330 static constexpr int foo();331};332template <Concept C4>333template <class T4>334constexpr int S2<C4>::foo() { return 2; }335 336template <Concept C5>337struct S3 {338 template <Concept C6>339 static constexpr int foo();340};341template <Concept C7>342template <Concept C8>343constexpr int S3<C7>::foo() { return 3; }344 345static_assert(S1<int>::foo<int>() == 1);346static_assert(S2<int>::foo<int>() == 2);347static_assert(S3<int>::foo<int>() == 3);348 349} // namespace GH62003350 351namespace MultilevelTemplateWithPartialSpecialization {352template <typename>353concept Concept = true;354 355namespace two_level {356template <typename T1, int>357struct W0 {358 template <typename T2>359 requires (Concept<T2>)360 void f(const T2 &);361};362 363template <typename T3>364struct W0<T3, 0> {365 template <typename T4>366 requires (Concept<T4>)367 void f(const T4 &);368};369 370template <typename T3>371template <typename T4>372requires (Concept<T4>)373inline void W0<T3, 0>::f(const T4 &) {}374} // namespace two_level375 376namespace three_level {377template <typename T1, int>378struct W0 {379 template <typename T2>380 struct W1 {381 template <typename T3>382 requires (Concept<T3>)383 void f(const T3 &);384 };385};386 387template <typename T4>388struct W0<T4, 0> {389 template <typename T5>390 struct W1 {391 template <typename T6>392 requires (Concept<T6>)393 void f(const T6 &);394 };395};396 397template <typename T7>398template <typename T8>399template <typename T9>400requires (Concept<T9>)401inline void W0<T7, 0>::W1<T8>::f(const T9 &) {}402} // namespace three_level403 404} // namespace MultilevelTemplateWithPartialSpecialization405 406namespace PR62697 {407template<typename>408concept c = true;409 410template<typename T>411struct s {412 void f() requires c<void(T)>;413};414 415template<typename T>416void s<T>::f() requires c<void(T)> { }417}418 419namespace GH62272 {420template<typename T> concept A = true;421template<typename T> struct X { A<T> auto f(); };422template<typename T> A<T> auto X<T>::f() {}423}424 425namespace GH65810 {426template<typename Param>427concept TrivialConcept =428requires(Param param) {429 (void)param;430};431 432template <typename T>433struct Base {434 class InnerClass;435};436 437template <typename T>438class Base<T>::InnerClass {439 template <typename Param>440 requires TrivialConcept<Param>441 int func(Param param) const;442};443 444template <typename T>445template <typename Param>446requires TrivialConcept<Param>447int Base<T>::InnerClass::func(Param param) const {448 return 0;449}450 451template<typename T>452struct Outermost {453 struct Middle {454 template<typename U>455 struct Innermost {456 template <typename Param>457 requires TrivialConcept<Param>458 int func(Param param) const;459 };460 };461};462 463template <typename T>464template <typename U>465template <typename Param>466requires TrivialConcept<Param>467int Outermost<T>::Middle::Innermost<U>::func(Param param) const {468 return 0;469}470 471} // namespace GH65810472 473namespace GH61763 {474template<typename T, typename U>475concept same_as = true;476 477template <class = void>478struct Foo {479 template <same_as<void> Param>480 friend struct Bar;481};482 483template struct Foo<>;484 485template <same_as<void> Param>486struct Bar {487};488 489 490template<typename T>491concept ok = true;492 493struct outer {494 template<typename T>495 requires ok<T>496 struct foo {};497};498 499template<typename U>500struct bar {501 template<typename T>502 requires ok<T>503 friend struct outer::foo;504};505 506bar<int> x;507} // namespace GH61763508 509 510namespace GH74314 {511template <class T, class U> constexpr bool is_same_v = __is_same(T, U);512template <class T, class U> constexpr bool is_not_same_v = !__is_same(T, U);513 514template <class Result>515concept something_interesting = requires {516 true;517 requires is_same_v<int, Result>;518};519 520template <class T>521struct X { // #defined-here522 void foo() requires requires { requires is_not_same_v<T, int>; };523 void bar(decltype(requires { requires is_not_same_v<T, int>; }));524};525 526template <class T>527void X<T>::foo() requires requires { requires something_interesting<T>; } {}528// expected-error@-1{{definition of 'foo' does not match any declaration}}529// expected-note@#defined-here{{defined here}}530// expected-note@-8{{member declaration nearly matches}}531 532template <class T>533void X<T>::foo() requires requires { requires is_not_same_v<T, int>; } {} // ok534 535template <class T>536void X<T>::bar(decltype(requires { requires something_interesting<T>; })) {}537// expected-error@-1{{definition of 'bar' does not match any declaration}}538// expected-note@#defined-here{{defined here}}539 540template <class T>541void X<T>::bar(decltype(requires { requires is_not_same_v<T, int>; })) {}542} // namespace GH74314543 544namespace GH56482 {545template <typename SlotMap>546concept slot_map_has_reserve = true;547 548template <typename T> struct Slot_map {549 constexpr void reserve() const noexcept550 requires slot_map_has_reserve<Slot_map>;551 552 constexpr void reserve(int) const noexcept553 requires slot_map_has_reserve<Slot_map<T>>;554};555 556template <typename T>557constexpr void Slot_map<T>::reserve() const noexcept558 requires slot_map_has_reserve<Slot_map<T>>559{}560 561template <typename T>562constexpr void Slot_map<T>::reserve(int) const noexcept563 requires slot_map_has_reserve<Slot_map>564{}565} // namespace GH56482566 567namespace GH74447 {568template <typename T> struct S {569 template <typename... U, int V>570 void test(T target, U... value)571 requires requires {572 target;573 sizeof...(value) == 1;574 V == 2;575 };576};577 578template <typename T>579template <typename... U, int V>580void S<T>::test(T target, U... value)581 requires requires {582 target;583 sizeof...(value) == 1;584 V == 2;585 }586{}587} // namespace GH74447588 589namespace GH72557 {590 591template <typename...>592concept IsAnyOf = true;593 594template <class... DerTs> struct DerivedCollection {595 template <class DerT>596 requires IsAnyOf<DerTs...>597 unsigned long index();598};599 600template <class... DerTs>601template <class DerT>602 requires IsAnyOf<DerTs...>603unsigned long DerivedCollection<DerTs...>::index() {}604 605} // namespace GH72557606 607namespace GH101735 {608 609template <class, class>610concept True = true;611 612template <typename T>613class A {614 template <typename... Ts>615 void method(Ts&... ts)616 requires requires (T t) {617 { t.method(static_cast<Ts &&>(ts)...) } -> True<void>;618 };619};620 621template <typename T>622template <typename... Ts>623void A<T>::method(Ts&... ts)624 requires requires (T t) {625 { t.method(static_cast<Ts &&>(ts)...) } -> True<void>;626 } {}627 628}629 630namespace GH63782 {631// GH63782 was also fixed by PR #80594, so let's add a test for it.632 633template<bool... Vals>634constexpr bool All = (Vals && ...);635 636template<bool... Bs>637class Class {638 template<typename>639 requires All<Bs...>640 void Foo();641};642 643template<bool... Bs>644template<typename>645requires All<Bs...>646void Class<Bs...>::Foo() {647};648 649} // namespace GH63782650 651namespace eve {652// Reduced from the "eve" project653 654template <typename... Ts>655struct tuple {656 template <int I0> requires(I0 <= sizeof...(Ts))657 constexpr auto split();658};659 660template <typename... Ts>661template <int I0>662requires(I0 <= sizeof...(Ts))663constexpr auto tuple<Ts...>::split(){664 return 0;665}666 667int foo() {668 tuple<int, float> x;669 return x.split<0>();670}671 672} // namespace eve673 674namespace GH93099 {675 676// Issues with sizeof...(expr)677 678template <typename T = int> struct C {679 template <int... N>680 requires(sizeof...(N) > 0)681 friend class NTTP;682 683 template <class... Tp>684 requires(sizeof...(Tp) > 0)685 friend class TP;686 687 template <template <typename> class... TTp>688 requires(sizeof...(TTp) > 0)689 friend class TTP;690};691 692template <int... N>693 requires(sizeof...(N) > 0)694class NTTP;695 696template <class... Tp>697 requires(sizeof...(Tp) > 0)698class TP;699 700template <template <typename> class... TTp>701 requires(sizeof...(TTp) > 0)702class TTP;703 704C v;705 706} // namespace GH93099707 708namespace GH115098 {709 710template <typename... Ts> struct c {711 template <typename T>712 requires(sizeof...(Ts) > 0)713 friend bool operator==(c, c);714};715 716template <typename... Ts> struct d {717 template <typename T>718 requires(sizeof...(Ts) > 0)719 friend bool operator==(d, d);720};721 722template struct c<int>;723template struct d<int, int>;724 725} // namespace GH115098726 727namespace GH123441 {728 729struct buf {730 constexpr buf(auto&&... initList) requires (sizeof...(initList) <= 8);731};732 733constexpr buf::buf(auto&&... initList) requires (sizeof...(initList) <= 8) {}734 735template <class>736struct buffer {737 constexpr buffer(auto&&... initList) requires (sizeof...(initList) <= 8);738};739 740template <class T>741constexpr buffer<T>::buffer(auto&&... initList) requires (sizeof...(initList) <= 8) {}742 743template <class...>744struct foo { // expected-note {{foo defined here}}745 constexpr foo(auto&&... initList)746 requires (sizeof...(initList) <= 8);747};748 749template <class... T>750constexpr foo<T...>::foo(auto&&... initList) // expected-error {{does not match any declaration}}751 requires (sizeof...(T) <= 8) {}752 753} // namespace GH123441754 755namespace GH114685 {756 757template <typename T> struct ptr {758 template <typename U>759 friend ptr<U> make_item(auto &&args)760 requires(sizeof(args) > 1);761};762 763template <typename U>764ptr<U> make_item(auto &&args)765 requires(sizeof(args) > 1) {}766 767ptr<char> p;768 769} // namespace GH114685770 771namespace GH123472 {772 773consteval bool fn() { return true; }774 775struct S {776 template <typename T>777 static consteval void mfn() requires (bool(&fn));778};779 780template <typename T>781consteval void S::mfn() requires (bool(&fn)) {}782 783}784 785 786namespace GH138255 {787 788template <typename... T>789concept C = true;790 791struct Func {792 template<typename... Ts>793 requires C<Ts...[0]>794 static auto buggy() -> void;795 796 template<typename... Ts>797 requires C<Ts...[0]>798 friend auto fr() -> void;799 800 template<typename... Ts>801 requires C<Ts...[0]>802 friend auto fr2() -> void{}; // expected-note{{previous definition is here}}803};804 805template<typename... Ts>806requires C<Ts...[0]>807auto Func::buggy() -> void {}808 809template<typename... Ts>810requires C<Ts...[0]>811auto fr() -> void {}812 813template<typename... Ts>814requires C<Ts...[0]>815auto fr2() -> void {} // expected-error{{redefinition of 'fr2'}}816 817 818template <typename... Ts>819requires C<Ts...[0]>820struct Class;821 822template <typename... Ts>823requires C<Ts...[0]>824struct Class;825 826 827template <typename...>828struct TplClass {829 template<typename... Ts>830 requires C<Ts...[0]>831 static auto buggy() -> void;832};833 834template<>835template<typename... Ts>836requires C<Ts...[0]>837auto TplClass<int>::buggy() -> void {}838 839}840 841namespace PackIndexExpr {842template <int... T>843concept C = true;844 845template <typename...> struct TplClass {846 template <int... Ts>847 requires C<Ts...[0]>848 static auto buggy() -> void;849};850 851template <>852template <int... Ts>853requires C<Ts...[0]>854auto TplClass<int>::buggy() -> void {}855}856 857namespace GH139476 {858 859namespace moo {860 template <typename T>861 constexpr bool baa = true;862 863 template <typename T> requires baa<T>864 void caw();865}866 867template <typename T> requires moo::baa<T>868void moo::caw() {}869 870}871 872namespace GH145521 {873 874template <typename X>875concept is_valid = true;876 877template<typename T>878class Nesting879{880public:881 template<typename Q> requires is_valid<Q>882 class Inner;883 884 template<typename Q> requires is_valid<Q>885 friend class Inner2;886};887 888template<typename T>889template<typename Q> requires is_valid<Q>890class Nesting<T>::Inner {};891 892template<typename Q> requires is_valid<Q>893class Inner2 {};894 895}896