summaryrefslogtreecommitdiffstats
path: root/clang/test
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test')
-rw-r--r--clang/test/CXX/expr/expr.prim/expr.prim.id/p3.cpp15
-rw-r--r--clang/test/CXX/temp/temp.constr/temp.constr.normal/p1.cpp18
-rw-r--r--clang/test/CXX/temp/temp.constr/temp.constr.order/class-template-partial-specializations.cpp50
-rw-r--r--clang/test/CXX/temp/temp.constr/temp.constr.order/function-templates.cpp89
-rw-r--r--clang/test/CXX/temp/temp.constr/temp.constr.order/var-template-partial-specializations.cpp53
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);
+
+
+
OpenPOWER on IntegriCloud