diff options
Diffstat (limited to 'clang/test/CXX/temp')
10 files changed, 82 insertions, 42 deletions
diff --git a/clang/test/CXX/temp/temp.constr/temp.constr.constr/function-templates.cpp b/clang/test/CXX/temp/temp.constr/temp.constr.constr/function-templates.cpp index c1a3a27fbea..99de7261a81 100644 --- a/clang/test/CXX/temp/temp.constr/temp.constr.constr/function-templates.cpp +++ b/clang/test/CXX/temp/temp.constr/temp.constr.constr/function-templates.cpp @@ -23,14 +23,13 @@ static_assert(is_same_v<decltype(dereference<int*>(nullptr)), int>); static_assert(is_same_v<decltype(dereference(2)), int>); // expected-error {{no matching function for call to 'dereference'}} static_assert(is_same_v<decltype(dereference<char>('a')), char>); // expected-error {{no matching function for call to 'dereference'}} - -template<typename T> requires T{} + T{} // expected-note {{because substituted constraint expression is ill-formed: invalid operands to binary expression ('A' and 'A')}} +template<typename T> requires (T{} + T{}) // expected-note {{because substituted constraint expression is ill-formed: invalid operands to binary expression ('A' and 'A')}} auto foo(T t) { // expected-note {{candidate template ignored: constraints not satisfied [with T = A]}} return t + t; } -template<typename T> requires !((T{} - T{}) && (T{} + T{})) || false +template<typename T> requires (!((T{} - T{}) && (T{} + T{})) || false) // expected-note@-1{{because substituted constraint expression is ill-formed: invalid operands to binary expression ('A' and 'A')}} // expected-note@-2{{and 'false' evaluated to false}} auto bar(T t) { // expected-note {{candidate template ignored: constraints not satisfied [with T = A]}} diff --git a/clang/test/CXX/temp/temp.constr/temp.constr.constr/non-function-templates.cpp b/clang/test/CXX/temp/temp.constr/temp.constr.constr/non-function-templates.cpp index 24caa5063a1..a25b22a9a15 100644 --- a/clang/test/CXX/temp/temp.constr/temp.constr.constr/non-function-templates.cpp +++ b/clang/test/CXX/temp/temp.constr/temp.constr.constr/non-function-templates.cpp @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s -template<typename T> requires sizeof(T) >= 2 // expected-note{{because 'sizeof(char) >= 2' (1 >= 2) evaluated to false}} +template<typename T> requires (sizeof(T) >= 2) // expected-note{{because 'sizeof(char) >= 2' (1 >= 2) evaluated to false}} struct A { static constexpr int value = sizeof(T); }; @@ -9,8 +9,8 @@ static_assert(A<int>::value == 4); static_assert(A<char>::value == 1); // expected-error{{constraints not satisfied for class template 'A' [with T = char]}} template<typename T, typename U> - requires sizeof(T) != sizeof(U) // expected-note{{because 'sizeof(int) != sizeof(char [4])' (4 != 4) evaluated to false}} - && sizeof(T) >= 4 // expected-note{{because 'sizeof(char) >= 4' (1 >= 4) evaluated to false}} + requires (sizeof(T) != sizeof(U) // expected-note{{because 'sizeof(int) != sizeof(char [4])' (4 != 4) evaluated to false}} + && sizeof(T) >= 4) // expected-note{{because 'sizeof(char) >= 4' (1 >= 4) evaluated to false}} constexpr int SizeDiff = sizeof(T) > sizeof(U) ? sizeof(T) - sizeof(U) : sizeof(U) - sizeof(T); static_assert(SizeDiff<int, char> == 3); @@ -44,16 +44,16 @@ static_assert(S<S2>::value); template<typename T> struct AA { - template<typename U> requires sizeof(U) == sizeof(T) // expected-note{{because 'sizeof(int [2]) == sizeof(int)' (8 == 4) evaluated to false}} + template<typename U> requires (sizeof(U) == sizeof(T)) // expected-note{{because 'sizeof(int [2]) == sizeof(int)' (8 == 4) evaluated to false}} struct B { static constexpr int a = 0; }; - template<typename U> requires sizeof(U) == sizeof(T) // expected-note{{because 'sizeof(int [2]) == sizeof(int)' (8 == 4) evaluated to false}} + template<typename U> requires (sizeof(U) == sizeof(T)) // expected-note{{because 'sizeof(int [2]) == sizeof(int)' (8 == 4) evaluated to false}} static constexpr int b = 1; - template<typename U> requires sizeof(U) == sizeof(T) // expected-note{{because 'sizeof(int [2]) == sizeof(int)' (8 == 4) evaluated to false}} + template<typename U> requires (sizeof(U) == sizeof(T)) // expected-note{{because 'sizeof(int [2]) == sizeof(int)' (8 == 4) evaluated to false}} static constexpr int getB() { // expected-note{{candidate template ignored: constraints not satisfied [with U = int [2]]}} return 2; } @@ -85,8 +85,8 @@ template<typename T> requires B<T>::type // expected-note{{in instantiation of t // expected-note@-1{{while substituting template arguments into constraint expression here}} struct C { }; -template<typename T> requires T{} // expected-error{{atomic constraint must be of type 'bool' (found 'int')}} +template<typename T> requires (T{}) // expected-error{{atomic constraint must be of type 'bool' (found 'int')}} struct D { }; static_assert(C<int>{}); // expected-note{{while checking constraint satisfaction for template 'C<int>' required here}} -static_assert(D<int>{}); // expected-note{{while checking constraint satisfaction for template 'D<int>' required here}}
\ No newline at end of file +static_assert(D<int>{}); // expected-note{{while checking constraint satisfaction for template 'D<int>' required here}} diff --git a/clang/test/CXX/temp/temp.constr/temp.constr.constr/partial-specializations.cpp b/clang/test/CXX/temp/temp.constr/temp.constr.constr/partial-specializations.cpp index 47bd2a55076..1ea4da29ee9 100644 --- a/clang/test/CXX/temp/temp.constr/temp.constr.constr/partial-specializations.cpp +++ b/clang/test/CXX/temp/temp.constr/temp.constr.constr/partial-specializations.cpp @@ -2,10 +2,10 @@ namespace class_templates { - template<typename T, typename U> requires sizeof(T) >= 4 // expected-note {{because 'sizeof(char) >= 4' (1 >= 4) evaluated to false}} + template<typename T, typename U> requires (sizeof(T) >= 4) // expected-note {{because 'sizeof(char) >= 4' (1 >= 4) evaluated to false}} struct is_same { static constexpr bool value = false; }; - template<typename T> requires sizeof(T*) >= 4 && sizeof(T) >= 4 + template<typename T> requires (sizeof(T*) >= 4 && sizeof(T) >= 4) struct is_same<T*, T*> { static constexpr bool value = true; }; static_assert(!is_same<char*, char*>::value); @@ -23,7 +23,7 @@ namespace class_templates // expected-note@-1{{while substituting template arguments into constraint expression here}} struct B<T*> {}; - template<typename T> requires T{} // expected-error{{atomic constraint must be of type 'bool' (found 'int')}} + template<typename T> requires (T{}) // expected-error{{atomic constraint must be of type 'bool' (found 'int')}} struct B<T**> {}; static_assert((B<int**>{}, true)); // expected-note{{while checking constraint satisfaction for class template partial specialization 'B<int *>' required here}} @@ -35,10 +35,10 @@ namespace class_templates namespace variable_templates { - template<typename T, typename U> requires sizeof(T) >= 4 + template<typename T, typename U> requires (sizeof(T) >= 4) constexpr bool is_same_v = false; - template<typename T> requires sizeof(T*) >= 4 && sizeof(T) >= 4 + template<typename T> requires (sizeof(T*) >= 4 && sizeof(T) >= 4) constexpr bool is_same_v<T*, T*> = true; static_assert(!is_same_v<char*, char*>); @@ -55,7 +55,7 @@ namespace variable_templates // expected-note@-1{{while substituting template arguments into constraint expression here}} constexpr bool v1<T*> = true; - template<typename T> requires T{} // expected-error{{atomic constraint must be of type 'bool' (found 'int')}} + template<typename T> requires (T{}) // expected-error{{atomic constraint must be of type 'bool' (found 'int')}} constexpr bool v1<T**> = true; static_assert(v1<int**>); // expected-note{{while checking constraint satisfaction for variable template partial specialization 'v1<int *>' required here}} diff --git a/clang/test/CXX/temp/temp.constr/temp.constr.decl/class-template-decl.cpp b/clang/test/CXX/temp/temp.constr/temp.constr.decl/class-template-decl.cpp index 5d5361f9c20..6f7b80e26a6 100644 --- a/clang/test/CXX/temp/temp.constr/temp.constr.decl/class-template-decl.cpp +++ b/clang/test/CXX/temp/temp.constr/temp.constr.decl/class-template-decl.cpp @@ -2,9 +2,9 @@ namespace nodiag { -template <typename T> requires bool(T()) +template <typename T> requires (bool(T())) struct A; -template <typename U> requires bool(U()) +template <typename U> requires (bool(U())) struct A; } // end namespace nodiag @@ -21,7 +21,7 @@ struct B; template <typename T> requires true // expected-note{{previous template declaration is here}} struct C; -template <typename T> requires !0 // expected-error{{requires clause differs in template redeclaration}} +template <typename T> requires (!0) // expected-error{{requires clause differs in template redeclaration}} struct C; } // end namespace diag @@ -29,15 +29,15 @@ struct C; namespace nodiag { struct AA { - template <typename T> requires someFunc(T()) + template <typename T> requires (someFunc(T())) struct A; }; -template <typename U> requires someFunc(U()) +template <typename U> requires (someFunc(U())) struct AA::A { }; struct AAF { - template <typename T> requires someFunc(T()) + template <typename T> requires (someFunc(T())) friend struct AA::A; }; diff --git a/clang/test/CXX/temp/temp.constr/temp.constr.decl/func-template-decl.cpp b/clang/test/CXX/temp/temp.constr/temp.constr.decl/func-template-decl.cpp index c83ab26059d..30fbec64eea 100644 --- a/clang/test/CXX/temp/temp.constr/temp.constr.decl/func-template-decl.cpp +++ b/clang/test/CXX/temp/temp.constr/temp.constr.decl/func-template-decl.cpp @@ -2,9 +2,9 @@ namespace nodiag { -template <typename T> requires bool(T()) +template <typename T> requires (bool(T())) int A(); -template <typename U> requires bool(U()) +template <typename U> requires (bool(U())) int A(); } // end namespace nodiag @@ -26,7 +26,7 @@ int orig::A(); template <typename T> requires true int orig::B(); // expected-error@-1{{out-of-line declaration of 'B' does not match any declaration in namespace 'diag::orig'}} -template <typename T> requires !0 +template <typename T> requires (!0) int orig::C(); // expected-error@-1{{out-of-line declaration of 'C' does not match any declaration in namespace 'diag::orig'}} @@ -35,11 +35,11 @@ int orig::C(); namespace nodiag { struct AA { - template <typename T> requires someFunc(T()) + template <typename T> requires (someFunc(T())) int A(); }; -template <typename T> requires someFunc(T()) +template <typename T> requires (someFunc(T())) int AA::A() { return sizeof(T); } } // end namespace nodiag diff --git a/clang/test/CXX/temp/temp.constr/temp.constr.decl/var-template-decl.cpp b/clang/test/CXX/temp/temp.constr/temp.constr.decl/var-template-decl.cpp index cf6874f12d3..eabb636b0bb 100644 --- a/clang/test/CXX/temp/temp.constr/temp.constr.decl/var-template-decl.cpp +++ b/clang/test/CXX/temp/temp.constr/temp.constr.decl/var-template-decl.cpp @@ -3,11 +3,11 @@ namespace nodiag { struct B { - template <typename T> requires bool(T()) + template <typename T> requires (bool(T())) static int A; }; -template <typename U> requires bool(U()) +template <typename U> requires (bool(U())) int B::A = int(U()); } // end namespace nodiag @@ -15,11 +15,11 @@ int B::A = int(U()); namespace diag { struct B { - template <typename T> requires bool(T()) // expected-note{{previous template declaration is here}} + template <typename T> requires (bool(T())) // expected-note{{previous template declaration is here}} static int A; }; -template <typename U> requires !bool(U()) // expected-error{{requires clause differs in template redeclaration}} +template <typename U> requires (!bool(U())) // expected-error{{requires clause differs in template redeclaration}} int B::A = int(U()); } // end namespace diag
\ No newline at end of file diff --git a/clang/test/CXX/temp/temp.constr/temp.constr.order/class-template-partial-specializations.cpp b/clang/test/CXX/temp/temp.constr/temp.constr.order/class-template-partial-specializations.cpp index 8c2f5526941..5d41035aa88 100644 --- a/clang/test/CXX/temp/temp.constr/temp.constr.order/class-template-partial-specializations.cpp +++ b/clang/test/CXX/temp/temp.constr/temp.constr.order/class-template-partial-specializations.cpp @@ -1,9 +1,12 @@ // RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s -template<typename T> requires sizeof(T) >= 4 +template<typename T> requires (sizeof(T) >= 4) +// expected-note@-1{{similar constraint expressions not considered equivalen}} class A{}; // expected-note{{template is declared here}} -template<typename T> requires sizeof(T) >= 4 && sizeof(T) <= 10 +template<typename T> requires (sizeof(T) >= 4 && sizeof(T) <= 10) +// expected-note@-1{{similar constraint expression here}} + class A<T>{}; // expected-error{{class template partial specialization is not more specialized than the primary template}} template<typename T> @@ -12,7 +15,7 @@ concept C1 = sizeof(T) >= 4; template<typename T> requires C1<T> class B{}; -template<typename T> requires C1<T> && sizeof(T) <= 10 +template<typename T> requires (C1<T> && sizeof(T) <= 10) class B<T>{}; template<typename T> @@ -48,3 +51,15 @@ struct F<T>{ enum{ value = 3 }; }; static_assert(F<unsigned>::value == 2); static_assert(F<char[10]>::value == 3); static_assert(F<char>::value == 1); + +// Make sure atomic constraints subsume each other only if their parameter +// mappings are identical. + +template<typename T, typename U> requires C2<T> +struct I { }; // expected-note {{template is declared here}} + +template<typename T, typename U> requires C2<U> +struct I<T, U> { }; // expected-error {{class template partial specialization is not more specialized than the primary template}} + +template<typename T, typename U> requires C2<T> && C2<U> +struct I<T, U> { }; diff --git a/clang/test/CXX/temp/temp.constr/temp.constr.order/function-templates.cpp b/clang/test/CXX/temp/temp.constr/temp.constr.order/function-templates.cpp index cc578fe0ad6..7f68369d528 100644 --- a/clang/test/CXX/temp/temp.constr/temp.constr.order/function-templates.cpp +++ b/clang/test/CXX/temp/temp.constr/temp.constr.order/function-templates.cpp @@ -1,9 +1,11 @@ // RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s -template<typename T> requires sizeof(T) >= 4 +template<typename T> requires (sizeof(T) >= 4) +// expected-note@-1{{similar constraint expressions not considered equivalent}} bool a() { return false; } // expected-note {{candidate function [with T = unsigned int]}} -template<typename T> requires sizeof(T) >= 4 && sizeof(T) <= 10 +template<typename T> requires (sizeof(T) >= 4 && sizeof(T) <= 10) +// expected-note@-1{{similar constraint expression here}} bool a() { return true; } // expected-note {{candidate function [with T = unsigned int]}} bool av = a<unsigned>(); // expected-error {{call to 'a' is ambiguous}} @@ -14,7 +16,7 @@ concept C1 = sizeof(T) >= 4; template<typename T> requires C1<T> constexpr bool b() { return false; } -template<typename T> requires C1<T> && sizeof(T) <= 10 +template<typename T> requires (C1<T> && sizeof(T) <= 10) constexpr bool b() { return true; } static_assert(b<int>()); @@ -86,4 +88,4 @@ static_assert(sizeof(g<int>())); template <unsigned> struct X {}; template <class...> int h(X<0>); template <unsigned b, class...> int h(X<b>); -static_assert(sizeof(h(X<0>{})));
\ No newline at end of file +static_assert(sizeof(h(X<0>{}))); diff --git a/clang/test/CXX/temp/temp.constr/temp.constr.order/var-template-partial-specializations.cpp b/clang/test/CXX/temp/temp.constr/temp.constr.order/var-template-partial-specializations.cpp index b40c77e70a1..cf88e34036d 100644 --- a/clang/test/CXX/temp/temp.constr/temp.constr.order/var-template-partial-specializations.cpp +++ b/clang/test/CXX/temp/temp.constr/temp.constr.order/var-template-partial-specializations.cpp @@ -1,9 +1,11 @@ // RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s -template<typename T> requires sizeof(T) >= 4 +template<typename T> requires (sizeof(T) >= 4) +// expected-note@-1{{similar constraint expressions not considered equivalent}} bool a = false; // expected-note{{template is declared here}} -template<typename T> requires sizeof(T) >= 4 && sizeof(T) <= 10 +template<typename T> requires (sizeof(T) >= 4 && sizeof(T) <= 10) +// expected-note@-1{{similar constraint expression here}} bool a<T> = true; // expected-error{{variable template partial specialization is not more specialized than the primary template}} template<typename T> @@ -12,7 +14,7 @@ concept C1 = sizeof(T) >= 4; template<typename T> requires C1<T> bool b = false; -template<typename T> requires C1<T> && sizeof(T) <= 10 +template<typename T> requires (C1<T> && sizeof(T) <= 10) bool b<T> = true; template<typename T> diff --git a/clang/test/CXX/temp/temp.explicit/p8.cpp b/clang/test/CXX/temp/temp.explicit/p8.cpp new file mode 100644 index 00000000000..72d22557899 --- /dev/null +++ b/clang/test/CXX/temp/temp.explicit/p8.cpp @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s + +template<typename T, typename S = char> requires (sizeof(T) + sizeof(S) < 10) +// expected-note@-1{{because 'sizeof(char [100]) + sizeof(char) < 10' (101 < 10) evaluated to false}} +void f(T t, S s) requires (sizeof(t) == 1 && sizeof(s) == 1) { }; +// expected-note@-1{{candidate template ignored: constraints not satisfied [with T = int, S = char]}} +// expected-note@-2{{because 'sizeof (t) == 1' (4 == 1) evaluated to false}} +// expected-note@-3{{candidate template ignored: constraints not satisfied [with T = char, S = short]}} +// expected-note@-4{{because 'sizeof (s) == 1' (2 == 1) evaluated to false}} +// expected-note@-5{{candidate template ignored: constraints not satisfied [with T = char [100], S = char]}} + +template<> +void f<int>(int t, char s) { }; +// expected-error@-1{{no function template matches function template specialization 'f'}} + +template<> +void f<char, short>(char t, short s) { }; +// expected-error@-1{{no function template matches function template specialization 'f'}} + +template<> +void f<char[100]>(char t[100], char s) { }; +// expected-error@-1{{no function template matches function template specialization 'f'}}
\ No newline at end of file |

