1 // RUN: %clang_cc1 %s -I%S -std=c++2a -verify
3 namespace std
{ struct type_info
; }
5 static_assert(requires
{ 0; });
6 static_assert(requires
{ "aaaa"; });
7 static_assert(requires
{ (0).da
; }); // expected-error{{member reference base type 'int' is not a structure or union}}
11 B
operator+(const B
&other
) const { return other
; }
14 C
operator+(C
&other
) const { return other
; }
17 template<typename T
> requires
requires (T a
, const T
& b
) { a
+ b
; }
18 // expected-note@-1{{because 'a + b' would be invalid: invalid operands to binary expression ('A' and 'const A')}}
19 // expected-note@-2{{because 'a + b' would be invalid: invalid operands to binary expression ('C' and 'const C')}}
23 using r1i2
= r1
<A
>; // expected-error{{constraints not satisfied for class template 'r1' [with T = A]}}
25 using r1i4
= r1
<C
>; // expected-error{{constraints not satisfied for class template 'r1' [with T = C]}}
27 struct D
{ void foo() {} };
29 template<typename T
> requires
requires (T a
) { a
.foo(); }
30 // expected-note@-1{{because 'a.foo()' would be invalid: no member named 'foo' in 'A'}}
31 // expected-note@-2{{because 'a.foo()' would be invalid: member reference base type 'int' is not a structure or union}}
32 // expected-note@-3{{because 'a.foo()' would be invalid: 'this' argument to member function 'foo' has type 'const D', but function is not marked const}}
35 using r2i1
= r2
<int>; // expected-error{{constraints not satisfied for class template 'r2' [with T = int]}}
36 using r2i2
= r2
<A
>; // expected-error{{constraints not satisfied for class template 'r2' [with T = A]}}
38 using r2i4
= r2
<const D
>; // expected-error{{constraints not satisfied for class template 'r2' [with T = const D]}}
40 template<typename T
> requires requires
{ sizeof(T
); }
41 // expected-note@-1{{because 'sizeof(T)' would be invalid: invalid application of 'sizeof' to an incomplete type 'void'}}
42 // expected-note@-2{{because 'sizeof(T)' would be invalid: invalid application of 'sizeof' to an incomplete type 'nonexistent'}}
48 using r3i4
= r3
<void>; // expected-error{{constraints not satisfied for class template 'r3' [with T = void]}}
49 using r3i4
= r3
<class nonexistent
>; // expected-error{{constraints not satisfied for class template 'r3' [with T = nonexistent]}}
51 template<typename T
> requires
requires (T t
) { 0; "a"; (void)'a'; }
55 using r4i2
= r4
<int[10]>;
56 using r4i3
= r4
<int(int)>;
58 template<class T
> void f(T
) = delete;
59 template<class T
> requires (sizeof(T
) == 1) void f(T
) { }
61 template<typename T
> requires
requires(T t
) { f(t
); }
62 // expected-note@-1{{because 'f(t)' would be invalid: call to deleted function 'f'}}
66 // expected-error@-1 {{constraints not satisfied for class template 'r5' [with T = int]}}
67 using r5i2
= r5
<char>;
71 struct non_default_constructible
{ non_default_constructible(T t
) { } };
74 template<typename T
> requires
requires(T t
) { typename E
<T
>::non_default_constructible
{}; }
75 // expected-note@-1 {{because 'typename E<T>::non_default_constructible{}' would be invalid: no matching constructor for initialization of 'typename E<int>::non_default_constructible'}}
79 // expected-error@-1 {{constraints not satisfied for class template 'r6' [with T = int]}}
81 template<typename T
> requires
requires(T t
) { typename E
<T
>::non_default_constructible(); }
82 // expected-note@-1 {{because 'typename E<T>::non_default_constructible()' would be invalid: no matching constructor for initialization of 'typename E<int>::non_default_constructible'}}
86 // expected-error@-1 {{constraints not satisfied for class template 'r7' [with T = int]}}
88 // C++ [expr.prim.req.simple] Example
89 namespace std_example
{
90 template<typename T
> concept C
=
91 requires (T a
, T b
) { // expected-note{{because 'a' would be invalid: argument may not have 'void' type}}
92 a
+ b
; // expected-note{{because 'a + b' would be invalid: invalid operands to binary expression ('int *' and 'int *')}}
95 static_assert(C
<int>);
96 template<C T
> struct C_check
{}; // expected-note{{because 'void' does not satisfy 'C'}} expected-note{{because 'int *' does not satisfy 'C'}}
97 using c1c1
= C_check
<void>; // expected-error{{constraints not satisfied for class template 'C_check' [with T = void]}}
98 using c1c2
= C_check
<int *>; // expected-error{{constraints not satisfied for class template 'C_check' [with T = int *]}}
101 // typeid() of an expression becomes potentially evaluated if the expression is
102 // of a polymorphic type.
103 class X
{ virtual ~X(); };
104 constexpr bool b
= requires (X
&x
) { static_cast<int(*)[(typeid(x
), 0)]>(nullptr); };
105 // expected-error@-1{{constraint variable 'x' cannot be used in an evaluated context}}
106 // expected-note@-2{{'x' declared here}}
108 namespace access_checks
{
109 namespace in_requires_expression
{
112 static constexpr bool foo();
113 static constexpr bool bar();
114 static constexpr bool baz();
115 static constexpr bool faz();
122 bool data_member
= true;
123 static const bool static_member
= true;
128 constexpr bool A
<x
>::foo() {
129 return requires(B b
) { b
.p(); };
131 static_assert(!A
<1>::foo());
132 static_assert(A
<0>::foo());
135 constexpr bool A
<x
>::bar() {
136 return requires() { B::static_member
; };
138 static_assert(!A
<1>::bar());
139 static_assert(A
<0>::bar());
142 constexpr bool A
<x
>::baz() {
143 return requires(B b
) { b
.data_member
; };
145 static_assert(!A
<1>::baz());
146 static_assert(A
<0>::baz());
149 constexpr bool A
<x
>::faz() {
150 return requires(B a
, B b
) {
156 static_assert(!A
<1>::faz());
157 static_assert(A
<0>::faz());
158 } // namespace in_requires_expression
160 namespace in_concepts
{
161 // Dependent access does not cause hard errors.
162 template<int N
> class A
;
164 template <> class A
<0> {
168 concept C1
= requires() { A
<N
>::f(); };
169 static_assert(!C1
<0>);
171 template <> class A
<1> {
175 static_assert(C1
<1>);
177 // Non-dependent access to private member is a hard error.
179 static void f() {} // expected-note 2{{implicitly declared private here}}
182 concept C2
= requires() { B::f(); }; // expected-error {{'f' is a private member}}
184 constexpr bool non_template_func() {
186 B::f(); // expected-error {{'f' is a private member}}
190 constexpr bool template_func() {
195 static_assert(!template_func
<0>());
196 static_assert(template_func
<1>());
197 } // namespace in_concepts
199 namespace in_trailing_requires
{
200 template <class> struct B
;
203 friend struct B
<short>;
206 template <class T
> struct B
{
207 static constexpr int index() requires requires
{ A::f(); } {
210 static constexpr int index() {
215 static_assert(B
<short>::index() == 1);
216 static_assert(B
<int>::index() == 2);
218 namespace missing_member_function
{
219 template <class T
> struct Use
;
223 friend struct Use
<short>;
225 template <class T
> struct Use
{
226 constexpr static int foo() requires
requires(X x
) { x
.a
; } {
229 constexpr static int bar() requires requires
{ X::B
; } {
235 // FIXME: Propagate diagnostic.
236 Use
<int>::foo(); //expected-error {{invalid reference to function 'foo': constraints not satisfied}}
237 static_assert(Use
<short>::foo() == 1);
239 } // namespace missing_member_function
240 } // namespace in_trailing_requires
241 } // namespace access_check