diff options
Diffstat (limited to 'clang/test')
5 files changed, 220 insertions, 5 deletions
diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.id/p3.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.id/p3.cpp index 1e10d4550ce..fb3978240af 100644 --- a/clang/test/CXX/expr/expr.prim/expr.prim.id/p3.cpp +++ b/clang/test/CXX/expr/expr.prim/expr.prim.id/p3.cpp @@ -75,11 +75,8 @@ static_assert(!IsTypePredicate<T1>); template<typename T, typename U, typename... Ts> concept OneOf = (Same<T, Ts> || ...); -template<typename... X> -constexpr bool S = OneOf<X..., int, int>; - -static_assert(S<int, long, int>); -static_assert(!S<long, int, char, char>); +static_assert(OneOf<int, long, int>); +static_assert(!OneOf<long, int, char, char>); namespace piecewise_substitution { template <typename T> @@ -178,3 +175,11 @@ template<typename T> concept AccessPrivate = T{}.f; static_assert(AccessPrivate<T4>); // expected-error@-1{{static_assert failed}} // expected-note@-2{{because 'T4' does not satisfy 'AccessPrivate'}} + +template<typename T, typename U> +// expected-note@-1{{template parameter is declared here}} +concept C8 = sizeof(T) > sizeof(U); + +template<typename... T> +constexpr bool B8 = C8<T...>; +// expected-error@-1{{pack expansion used as argument for non-pack parameter of concept}} diff --git a/clang/test/CXX/temp/temp.constr/temp.constr.normal/p1.cpp b/clang/test/CXX/temp/temp.constr/temp.constr.normal/p1.cpp new file mode 100644 index 00000000000..387b75c4ef0 --- /dev/null +++ b/clang/test/CXX/temp/temp.constr/temp.constr.normal/p1.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s + +template<typename T> concept True = true; +template<typename T> concept Foo = True<T*>; +template<typename T> concept Bar = Foo<T&>; +template<typename T> requires Bar<T> struct S { }; +template<typename T> requires Bar<T> && true struct S<T> { }; + +template<typename T> concept True2 = sizeof(T) >= 0; +template<typename T> concept Foo2 = True2<T*>; +// expected-error@-1{{'type name' declared as a pointer to a reference of type 'type-parameter-0-0 &'}} +template<typename T> concept Bar2 = Foo2<T&>; +// expected-note@-1{{while substituting into concept arguments here; substitution failures not allowed in concept arguments}} +template<typename T> requires Bar2<T> struct S2 { }; +// expected-note@-1{{template is declared here}} +template<typename T> requires Bar2<T> && true struct S2<T> { }; +// expected-error@-1{{class template partial specialization is not more specialized than the primary template}} +// expected-note@-2{{while calculating associated constraint of template 'S2' here}} 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 new file mode 100644 index 00000000000..8c2f5526941 --- /dev/null +++ b/clang/test/CXX/temp/temp.constr/temp.constr.order/class-template-partial-specializations.cpp @@ -0,0 +1,50 @@ +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s + +template<typename T> requires sizeof(T) >= 4 +class A{}; // expected-note{{template is declared here}} + +template<typename T> requires sizeof(T) >= 4 && sizeof(T) <= 10 +class A<T>{}; // expected-error{{class template partial specialization is not more specialized than the primary template}} + +template<typename T> +concept C1 = sizeof(T) >= 4; + +template<typename T> requires C1<T> +class B{}; + +template<typename T> requires C1<T> && sizeof(T) <= 10 +class B<T>{}; + +template<typename T> +concept C2 = sizeof(T) > 1 && sizeof(T) <= 8; + +template<typename T> +class C{}; + +template<typename T> requires C1<T> +class C<T>{}; + +template<typename T> +class D{}; // expected-note{{previous definition is here}} + +template<typename T> +class D<T>{}; // expected-error{{class template partial specialization does not specialize any template argument; to define the primary template, remove the template argument list}} expected-error{{redefinition of 'D'}} + +template<typename T> requires C1<T> // expected-note{{previous template declaration is here}} +class E{}; + +template<typename T> // expected-error{{requires clause differs in template redeclaration}} +class E<T>{}; // expected-error{{class template partial specialization does not specialize any template argument; to define the primary template, remove the template argument list}} + +template<typename T> +struct F{ enum{ value = 1 }; }; + +template<typename T> requires C1<T> && C2<T> +struct F<T>{ enum{ value = 2 }; }; + +template<typename T> requires C1<T> || C2<T> +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); 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 new file mode 100644 index 00000000000..cc578fe0ad6 --- /dev/null +++ b/clang/test/CXX/temp/temp.constr/temp.constr.order/function-templates.cpp @@ -0,0 +1,89 @@ +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s + +template<typename T> requires sizeof(T) >= 4 +bool a() { return false; } // expected-note {{candidate function [with T = unsigned int]}} + +template<typename T> requires sizeof(T) >= 4 && sizeof(T) <= 10 +bool a() { return true; } // expected-note {{candidate function [with T = unsigned int]}} + +bool av = a<unsigned>(); // expected-error {{call to 'a' is ambiguous}} + +template<typename T> +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 +constexpr bool b() { return true; } + +static_assert(b<int>()); +static_assert(!b<int[10]>()); + +template<typename T> +concept C2 = sizeof(T) > 1 && sizeof(T) <= 8; + +template<typename T> +bool c() { return false; } + +template<typename T> requires C1<T> +bool c() { return true; } + +template<typename T> requires C1<T> +constexpr bool d() { return false; } + +template<typename T> +constexpr bool d() { return true; } + +static_assert(!d<int>()); + +template<typename T> +constexpr int e() { return 1; } + +template<typename T> requires C1<T> && C2<T> +constexpr int e() { return 2; } + +template<typename T> requires C1<T> || C2<T> +constexpr int e() { return 3; } + +static_assert(e<unsigned>() == 2); +static_assert(e<char[10]>() == 3); +static_assert(e<char>() == 1); + +template<class T, class U> +concept BiggerThan = sizeof(T) > sizeof(U); + +template<class T> +concept BiggerThanInt = BiggerThan<T, int>; + +template<class T, class U> requires BiggerThan<T, U> +void f() { } +// expected-note@-1 {{candidate function [with T = long long, U = int]}} + +template<class T, class U> requires BiggerThanInt<T> +void f() { } +// expected-note@-1 {{candidate function [with T = long long, U = int]}} + +static_assert(sizeof(f<long long, int>())); +// expected-error@-1 {{call to 'f' is ambiguous}} + +template<typename T> +concept C3 = true; + +template<typename T> +concept C4 = true && C3<T>; + +template<typename T> requires C3<void> +int g() { } + +template<typename T> requires C4<void> +int g() { } + +static_assert(sizeof(g<int>())); + +// Regression - used template parameter detection when only first out of +// multiple parameters are used +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 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 new file mode 100644 index 00000000000..b40c77e70a1 --- /dev/null +++ b/clang/test/CXX/temp/temp.constr/temp.constr.order/var-template-partial-specializations.cpp @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s + +template<typename T> requires sizeof(T) >= 4 +bool a = false; // expected-note{{template is declared here}} + +template<typename T> requires sizeof(T) >= 4 && sizeof(T) <= 10 +bool a<T> = true; // expected-error{{variable template partial specialization is not more specialized than the primary template}} + +template<typename T> +concept C1 = sizeof(T) >= 4; + +template<typename T> requires C1<T> +bool b = false; + +template<typename T> requires C1<T> && sizeof(T) <= 10 +bool b<T> = true; + +template<typename T> +concept C2 = sizeof(T) > 1 && sizeof(T) <= 8; + +template<typename T> +bool c = false; + +template<typename T> requires C1<T> +bool c<T> = true; + +template<typename T> +bool d = false; + +template<typename T> +bool d<T> = true; // expected-error{{variable template partial specialization does not specialize any template argument; to define the primary template, remove the template argument list}} + +template<typename T> requires C1<T> +bool e = false; + +template<typename T> +bool e<T> = true; // expected-error{{variable template partial specialization does not specialize any template argument; to define the primary template, remove the template argument list}} + +template<typename T> +constexpr int f = 1; + +template<typename T> requires C1<T> && C2<T> +constexpr int f<T> = 2; + +template<typename T> requires C1<T> || C2<T> +constexpr int f<T> = 3; + +static_assert(f<unsigned> == 2); +static_assert(f<char[10]> == 3); +static_assert(f<char> == 1); + + + |

