// RUN: %clang_cc1 -std=c++20 -verify %s namespace GH53213 { template concept c = requires(T t) { f(t); }; // #CDEF auto f(c auto); // #FDEF void g() { f(0); // expected-error@-1{{no matching function for call to 'f'}} // expected-note@#FDEF{{constraints not satisfied}} // expected-note@#FDEF{{because 'int' does not satisfy 'c'}} // expected-note@#CDEF{{because 'f(t)' would be invalid: no matching function for call to 'f'}} } } // namespace GH53213 namespace GH45736 { struct constrained; template struct type { }; template constexpr bool f(type) { return true; } template concept matches = f(type()); struct constrained { template requires matches explicit constrained(U value) { } }; bool f(constrained const &) { return true; } struct outer { constrained state; }; bool f(outer const & x) { return f(x.state); } } // namespace GH45736 namespace DirectRecursiveCheck { template concept NotInf = true; template concept Inf = requires(T& v){ // #INF_REQ {begin(v)}; // #INF_BEGIN_EXPR }; void begin(NotInf auto& v){ } // #NOTINF_BEGIN // This lookup should fail, since it results in a recursive check. // However, this is a 'hard failure'(not a SFINAE failure or constraints // violation), so it needs to cause the entire lookup to fail. void begin(Inf auto& v){ } // #INF_BEGIN struct my_range{ } rng; void baz() { auto it = begin(rng); // #BEGIN_CALL // expected-error@#INF_BEGIN {{satisfaction of constraint 'Inf' depends on itself}} // expected-note@#INF_BEGIN {{while substituting template arguments into constraint expression here}} // expected-note@#INF_BEGIN_EXPR {{while checking constraint satisfaction for template 'begin' required here}} // expected-note@#INF_BEGIN_EXPR {{while substituting deduced template arguments into function template 'begin'}} // expected-note@#INF_BEGIN_EXPR {{in instantiation of requirement here}} // expected-note@#INF_REQ {{while substituting template arguments into constraint expression here}} // expected-note@#INF_BEGIN {{while checking the satisfaction of concept 'Inf' requested here}} // expected-note@#INF_BEGIN {{while substituting template arguments into constraint expression here}} // expected-note@#BEGIN_CALL {{while checking constraint satisfaction for template 'begin' required here}} // expected-note@#BEGIN_CALL {{while substituting deduced template arguments into function template}} // Fallout of the failure is failed lookup, which is necessary to stop odd // cascading errors. // expected-error@#BEGIN_CALL {{no matching function for call to 'begin'}} // expected-note@#NOTINF_BEGIN {{candidate function}} // expected-note@#INF_BEGIN{{candidate template ignored: constraints not satisfied}} } } // namespace DirectRecursiveCheck namespace GH50891 { template concept Numeric = requires(T a) { // #NUMERIC foo(a); // #FOO_CALL }; struct Deferred { friend void foo(Deferred); template operator TO(); // #OP_TO }; static_assert(Numeric); // #STATIC_ASSERT // expected-error@#NUMERIC{{satisfaction of constraint 'requires (T a) { foo(a); }' depends on itself}} // expected-note@#NUMERIC {{while substituting template arguments into constraint expression here}} // expected-note@#OP_TO {{while checking the satisfaction of concept 'Numeric' requested here}} // expected-note@#OP_TO {{while substituting template arguments into constraint expression here}} // expected-note@#FOO_CALL {{while checking constraint satisfaction for template}} // expected-note@#FOO_CALL {{while substituting deduced template arguments into function template}} // expected-note@#FOO_CALL {{in instantiation of requirement here}} // expected-note@#NUMERIC {{while substituting template arguments into constraint expression here}} // expected-error@#STATIC_ASSERT {{static assertion failed}} // expected-note@#STATIC_ASSERT{{while checking the satisfaction of concept 'Numeric' requested here}} // expected-note@#STATIC_ASSERT{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}} } // namespace GH50891 namespace GH60323 { // This should not diagnose, as it does not depend on itself. struct End { template void go(T t) { } template auto endparens(T t) requires requires { go(t); } { return go(t); } }; struct Size { template auto go(T t) { return End().endparens(t); } template auto sizeparens(T t) requires requires { go(t); } { return go(t); } }; int f() { int i = 42; Size().sizeparens(i); } } namespace CWG2369_Regressions { // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109397 namespace GCC_103997 { template concept streamable = requires(_stream &s, _type &&v) { s << static_cast<_type &&>(v); }; struct type_a { template type_a &operator<<(_arg &&) { // std::clog << "type_a" << std::endl; return *this; } }; struct type_b { type_b &operator<<(type_a const &) { // std::clog << "type_b" << std::endl; return *this; } }; struct type_c { type_b b; template requires streamable<_arg, type_b> friend type_c &operator<<(type_c &c, _arg &&a) { // std::clog << "type_c" << std::endl; c.b << static_cast<_arg &&>(a); return c; } }; void foo() { type_a a; type_c c; a << c; // "type_a\n" (gcc gives error here) c << a; // "type_c\ntype_b\n" } } // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108393 namespace GCC_108393 { template struct iterator_traits {}; template requires requires(T __t, T __u) { __t == __u; } struct iterator_traits {}; template concept C = requires { typename iterator_traits::A; }; struct unreachable_sentinel_t { template friend constexpr bool operator==(unreachable_sentinel_t, const _Iter&) noexcept; }; template struct S {}; static_assert(!C>); } // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107429 namespace GCC_107429 { struct tag_foo { } inline constexpr foo; struct tag_bar { } inline constexpr bar; template auto f(tag_foo, T... x) { return (x + ...); } template concept fooable = requires (T... x) { f(foo, x...); }; template requires (fooable) auto f(tag_bar, T... x) { return f(foo, x...); } auto test() { return f(bar, 1, 2, 3); } } namespace GCC_99599 { struct foo_tag {}; struct bar_tag {}; template concept fooable = requires(T it) { invoke_tag(foo_tag{}, it); // <-- here }; template auto invoke_tag(foo_tag, T in) { return in; } template auto invoke_tag(bar_tag, T it) { return it; } int main() { // Neither line below compiles in GCC 11, independently of the other return invoke_tag(foo_tag{}, 2) + invoke_tag(bar_tag{}, 2); } } // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99599#c22 namespace GCC_99599_2 { template class indirect { public: template requires requires (const T& t, const U& u) { t == u; } friend constexpr bool operator==(const indirect&, const U&) { return false; } private: T* _M_ptr{}; }; indirect i; bool b = i == 1; } namespace GCC_99599_3 { template struct S { T t; }; template concept C = sizeof(S) > 0; struct I; struct from_range_t { explicit from_range_t() = default; }; inline constexpr from_range_t from_range; template concept FromRange = __is_same_as (T, from_range_t); //#define WORKAROUND #ifdef WORKAROUND template void f(U, T*); #else template void f(from_range_t, T*); #endif void f(...); void g(I* p) { f(0, p); } } namespace GCC_99599_4 { struct A { A(...); }; template void f(A, T) { } int main() { f(42, 24); } } namespace FAILED_GCC_110160 { // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110160 // Current heuristic FAILED; GCC trunk also failed // https://godbolt.org/z/r3Pz9Tehz #if 0 #include #include template concept StreamCanReceiveString = requires(T& t, std::string s) { { t << s }; }; struct NotAStream {}; struct UnrelatedType {}; template S& operator<<(S& s, UnrelatedType) { return s; } static_assert(!StreamCanReceiveString); static_assert(StreamCanReceiveString); #endif } }