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