167c608a9SSaar Raz // RUN: %clang_cc1 -std=c++2a -x c++ -verify %s 2fdf80e86SSaar Raz 3b65b1f32SSaar Raz template<typename T> requires (sizeof(T) >= 2) // expected-note{{because 'sizeof(char) >= 2' (1 >= 2) evaluated to false}} 4fdf80e86SSaar Raz struct A { 5fdf80e86SSaar Raz static constexpr int value = sizeof(T); 6fdf80e86SSaar Raz }; 7fdf80e86SSaar Raz 8fdf80e86SSaar Raz static_assert(A<int>::value == 4); 9fdf80e86SSaar Raz static_assert(A<char>::value == 1); // expected-error{{constraints not satisfied for class template 'A' [with T = char]}} 10fdf80e86SSaar Raz 11fdf80e86SSaar Raz template<typename T, typename U> 12b65b1f32SSaar Raz requires (sizeof(T) != sizeof(U) // expected-note{{because 'sizeof(int) != sizeof(char[4])' (4 != 4) evaluated to false}} 13b65b1f32SSaar Raz && sizeof(T) >= 4) // expected-note{{because 'sizeof(char) >= 4' (1 >= 4) evaluated to false}} 14fdf80e86SSaar Raz constexpr int SizeDiff = sizeof(T) > sizeof(U) ? sizeof(T) - sizeof(U) : sizeof(U) - sizeof(T); 15fdf80e86SSaar Raz 16fdf80e86SSaar Raz static_assert(SizeDiff<int, char> == 3); 17fdf80e86SSaar Raz static_assert(SizeDiff<int, char[4]> == 0); // expected-error{{constraints not satisfied for variable template 'SizeDiff' [with T = int, U = char[4]]}} 18fdf80e86SSaar Raz static_assert(SizeDiff<char, int> == 3); // expected-error{{constraints not satisfied for variable template 'SizeDiff' [with T = char, U = int]}} 19fdf80e86SSaar Raz 20fdf80e86SSaar Raz template<typename... Ts> 21fdf80e86SSaar Raz requires ((sizeof(Ts) == 4) || ...) // expected-note{{because 'sizeof(char) == 4' (1 == 4) evaluated to false}} expected-note{{'sizeof(long long) == 4' (8 == 4) evaluated to false}} expected-note{{'sizeof(int[20]) == 4' (80 == 4) evaluated to false}} 22fdf80e86SSaar Raz constexpr auto SumSizes = (sizeof(Ts) + ...); 23fdf80e86SSaar Raz 24fdf80e86SSaar Raz static_assert(SumSizes<char, long long, int> == 13); 25fdf80e86SSaar Raz static_assert(SumSizes<char, long long, int[20]> == 89); // expected-error{{constraints not satisfied for variable template 'SumSizes' [with Ts = <char, long long, int[20]>]}} 26fdf80e86SSaar Raz 27fdf80e86SSaar Raz template<typename T> 28fdf80e86SSaar Raz concept IsBig = sizeof(T) > 100; // expected-note{{because 'sizeof(int) > 100' (4 > 100) evaluated to false}} 29fdf80e86SSaar Raz 30fdf80e86SSaar Raz template<typename T> 31fdf80e86SSaar Raz requires IsBig<T> // expected-note{{'int' does not satisfy 'IsBig'}} 32fdf80e86SSaar Raz using BigPtr = T*; 33fdf80e86SSaar Raz 34fdf80e86SSaar Raz static_assert(sizeof(BigPtr<int>)); // expected-error{{constraints not satisfied for alias template 'BigPtr' [with T = int]}}}} 35fdf80e86SSaar Raz 36fdf80e86SSaar Raz template<typename T> requires T::value // expected-note{{because substituted constraint expression is ill-formed: type 'int' cannot be used prior to '::' because it has no members}} 37fdf80e86SSaar Raz struct S { static constexpr bool value = true; }; 38fdf80e86SSaar Raz 39fdf80e86SSaar Raz struct S2 { static constexpr bool value = true; }; 40fdf80e86SSaar Raz 41fdf80e86SSaar Raz static_assert(S<int>::value); // expected-error{{constraints not satisfied for class template 'S' [with T = int]}} 42fdf80e86SSaar Raz static_assert(S<S2>::value); 43fdf80e86SSaar Raz 44fdf80e86SSaar Raz template<typename T> 45fdf80e86SSaar Raz struct AA 46fdf80e86SSaar Raz { 47b65b1f32SSaar Raz template<typename U> requires (sizeof(U) == sizeof(T)) // expected-note{{because 'sizeof(int[2]) == sizeof(int)' (8 == 4) evaluated to false}} 48fdf80e86SSaar Raz struct B 49fdf80e86SSaar Raz { 50fdf80e86SSaar Raz static constexpr int a = 0; 51fdf80e86SSaar Raz }; 52fdf80e86SSaar Raz 53b65b1f32SSaar Raz template<typename U> requires (sizeof(U) == sizeof(T)) // expected-note{{because 'sizeof(int[2]) == sizeof(int)' (8 == 4) evaluated to false}} 54fdf80e86SSaar Raz static constexpr int b = 1; 55fdf80e86SSaar Raz 56b65b1f32SSaar Raz template<typename U> requires (sizeof(U) == sizeof(T)) // expected-note{{because 'sizeof(int[2]) == sizeof(int)' (8 == 4) evaluated to false}} getBAA57fdf80e86SSaar Raz static constexpr int getB() { // expected-note{{candidate template ignored: constraints not satisfied [with U = int[2]]}} 58fdf80e86SSaar Raz return 2; 59fdf80e86SSaar Raz } 60fdf80e86SSaar Raz fooAA61fdf80e86SSaar Raz static auto foo() 62fdf80e86SSaar Raz { 63fdf80e86SSaar Raz return B<T[2]>::a; // expected-error{{constraints not satisfied for class template 'B' [with U = int[2]]}} 64fdf80e86SSaar Raz } 65fdf80e86SSaar Raz foo1AA66fdf80e86SSaar Raz static auto foo1() 67fdf80e86SSaar Raz { 68fdf80e86SSaar Raz return b<T[2]>; // expected-error{{constraints not satisfied for variable template 'b' [with U = int[2]]}} 69fdf80e86SSaar Raz } 70fdf80e86SSaar Raz foo2AA71fdf80e86SSaar Raz static auto foo2() 72fdf80e86SSaar Raz { 73fdf80e86SSaar Raz return AA<T>::getB<T[2]>(); // expected-error{{no matching function for call to 'getB'}} 74fdf80e86SSaar Raz } 75fdf80e86SSaar Raz }; 76fdf80e86SSaar Raz 77fdf80e86SSaar Raz constexpr auto x = AA<int>::foo(); // expected-note{{in instantiation of member function 'AA<int>::foo' requested here}} 78fdf80e86SSaar Raz constexpr auto x1 = AA<int>::foo1(); // expected-note{{in instantiation of member function 'AA<int>::foo1' requested here}} 79fdf80e86SSaar Raz constexpr auto x2 = AA<int>::foo2(); // expected-note{{in instantiation of member function 'AA<int>::foo2' requested here}} 80fdf80e86SSaar Raz 81fdf80e86SSaar Raz template<typename T> 82fdf80e86SSaar Raz struct B { using type = typename T::type; }; // expected-error{{type 'int' cannot be used prior to '::' because it has no members}} 83fdf80e86SSaar Raz 84fdf80e86SSaar Raz template<typename T> requires B<T>::type // expected-note{{in instantiation of template class 'B<int>' requested here}} 85fdf80e86SSaar Raz // expected-note@-1{{while substituting template arguments into constraint expression here}} 86fdf80e86SSaar Raz struct C { }; 87fdf80e86SSaar Raz 88b65b1f32SSaar Raz template<typename T> requires (T{}) // expected-error{{atomic constraint must be of type 'bool' (found 'int')}} 89fdf80e86SSaar Raz struct D { }; 90fdf80e86SSaar Raz 91fdf80e86SSaar Raz static_assert(C<int>{}); // expected-note{{while checking constraint satisfaction for template 'C<int>' required here}} 92fdf80e86SSaar Raz static_assert(D<int>{}); // expected-note{{while checking constraint satisfaction for template 'D<int>' required here}} 93*babdef27SErich Keane 94*babdef27SErich Keane // Test the delayed instantiation, the 'foo' implementation shouldn't cause the 95*babdef27SErich Keane // constraint failure(or crash!) until the use to create 'y'. 96*babdef27SErich Keane namespace DelayedInst { 97*babdef27SErich Keane template <unsigned I> 98*babdef27SErich Keane struct AAA { 99*babdef27SErich Keane template <typename T> 100*babdef27SErich Keane requires(sizeof(T) == I) // expected-note {{because 'sizeof(int) == 5U' (4 == 5) evaluated to false}} 101*babdef27SErich Keane struct B { 102*babdef27SErich Keane static constexpr int a = 0; 103*babdef27SErich Keane }; 104*babdef27SErich Keane fooDelayedInst::AAA105*babdef27SErich Keane static constexpr auto foo() { 106*babdef27SErich Keane return B<int>::a; // expected-error{{constraints not satisfied for class template 'B' [with T = int]}} 107*babdef27SErich Keane } 108*babdef27SErich Keane }; 109*babdef27SErich Keane 110*babdef27SErich Keane constexpr auto x = AAA<4>::foo(); 111*babdef27SErich Keane constexpr auto y = AAA<5>::foo(); // expected-note {{in instantiation of member function 'DelayedInst::AAA<5>::foo' requested here}} 112*babdef27SErich Keane 113*babdef27SErich Keane } // namespace DelayedInst 114