// RUN: %clang_cc1 -std=c++2a -x c++ %s -verify=expected,cxx20 // RUN: %clang_cc1 -std=c++2c -x c++ %s -verify template concept C1 = sizeof(U) >= 4; // sizeof(U) >= 4 [U = U (decltype(T))] template concept C2 = C1; // sizeof(U) >= 4 [U = V (decltype(Y{}))] template constexpr int foo() requires C2 { return 1; } // #cand1 // sizeof(U) >= 4 [U = W (decltype(int{}))] template constexpr int foo() requires C1<1, X> && true { return 2; } // #cand2 // sizeof(U) >= 4 [U = X (decltype(1))] static_assert(foo<'a'>() == 2); template constexpr int foo() requires C2 && true { return 3; } // #cand3 // sizeof(U) >= 4 [U = Z (decltype(long long{}))] static_assert(foo<'a'>() == 3); // expected-error@-1{{call to 'foo' is ambiguous}} // expected-note@#cand2 {{candidate function}} // expected-note@#cand3 {{candidate function}} namespace case1 { template concept C1 = sizeof(T) >= 4; // #case1_C1 template concept C2 = C1; // #case1_C2 template constexpr int foo() requires C2 { return 1; } // #case1_foo1 template constexpr int foo() requires C1 && true { return 2; } // #case1_foo2 static_assert(foo() == 2); // expected-error@-1{{no matching function for call to 'foo'}} // expected-note@#case1_foo1{{candidate template ignored: constraints not satisfied [with T = char, W = 'a']}} // expected-note@#case1_foo1{{because 'C2' evaluated to false}} // expected-note@#case1_C2{{because 'C1' evaluated to false}} // expected-note@#case1_C1{{because 'sizeof ('\x00') >= 4' (1 >= 4) evaluated to false}} // expected-note@#case1_foo2{{candidate template ignored: constraints not satisfied [with T = char, X = 'a']}} // expected-note@#case1_foo2{{because 'C1' evaluated to false}} // expected-note@#case1_C1{{because 'sizeof ('\x00') >= 4' (1 >= 4) evaluated to false}} static_assert(foo() == 2); } namespace packs { template concept C1 = sizeof(U) >= 4; template concept C2 = C1; template constexpr int foo() requires (C2 && ...) { return 1; } // #packs-cand1 template constexpr int foo() requires (C1<1, X> && ...) && true { return 2; } // #packs-cand2 static_assert(foo<'a'>() == 2); // cxx20-error@-1{{call to 'foo' is ambiguous}} // cxx20-note@#packs-cand1 {{candidate function}} // cxx20-note@#packs-cand2 {{candidate function}} } namespace case2 { template concept C1 = sizeof(decltype(T)) >= 0; template concept C2 = C1; template constexpr int foo() requires C2 { return 1; } template constexpr int foo() requires C1<0> && true { return 2; } static_assert(foo<0>() == 2); } namespace case3 { template concept C1 = sizeof(decltype(T)) >= 0; template concept C2 = C1; template constexpr int foo() requires C2 { return 1; } // #case3_foo1 template constexpr int foo() requires C1<1> && true { return 2; } // #case3_foo2 static_assert(foo<0>() == 2); // expected-error@-1{{call to 'foo' is ambiguous}} // expected-note@#case3_foo1 {{candidate function}} // expected-note@#case3_foo2 {{candidate function}} }