xref: /llvm-project/clang/test/CXX/expr/expr.prim/expr.prim.req/requires-expr.cpp (revision bb78a0b33496fb0140cec1a92a689505f53253b7)
167c608a9SSaar Raz // RUN: %clang_cc1 -std=c++2a -x c++ %s -verify
2a0f50d73SSaar Raz 
3a0f50d73SSaar Raz using A = int;
4a0f50d73SSaar Raz 
5a0f50d73SSaar Raz template<typename T, typename U>
6a0f50d73SSaar Raz constexpr bool is_same_v = false;
7a0f50d73SSaar Raz 
8a0f50d73SSaar Raz template<typename T>
9a0f50d73SSaar Raz constexpr bool is_same_v<T, T> = true;
10a0f50d73SSaar Raz 
11a0f50d73SSaar Raz template<typename T, typename U>
12a0f50d73SSaar Raz concept same_as = is_same_v<T, U>;
13a0f50d73SSaar Raz 
14a0f50d73SSaar Raz static_assert(requires { requires true; 0; typename A;
15a0f50d73SSaar Raz                          { 0 } -> same_as<int>; });
16a0f50d73SSaar Raz static_assert(is_same_v<bool, decltype(requires { requires false; })>);
17a0f50d73SSaar Raz 
18a0f50d73SSaar Raz // Check that requires expr is an unevaluated context.
19a0f50d73SSaar Raz struct Y {
20a0f50d73SSaar Raz   int i;
21a0f50d73SSaar Raz   static constexpr bool r = requires { i; };
22a0f50d73SSaar Raz };
23a0f50d73SSaar Raz 
24a0f50d73SSaar Raz template<typename T> requires requires (T t) {
25a0f50d73SSaar Raz   requires false; // expected-note{{because 'false' evaluated to false}}
26a0f50d73SSaar Raz   requires false;
27a0f50d73SSaar Raz   requires requires {
28a0f50d73SSaar Raz     requires false;
29a0f50d73SSaar Raz   };
30a0f50d73SSaar Raz }
31a0f50d73SSaar Raz struct r1 { };
32a0f50d73SSaar Raz 
33a0f50d73SSaar Raz using r1i = r1<int>;
34a0f50d73SSaar Raz // expected-error@-1 {{constraints not satisfied for class template 'r1' [with T = int]}}
35a0f50d73SSaar Raz 
36a0f50d73SSaar Raz template<typename T> requires requires (T t) {
37a0f50d73SSaar Raz   requires requires {
38a0f50d73SSaar Raz     requires false; // expected-note{{because 'false' evaluated to false}}
39a0f50d73SSaar Raz   };
40a0f50d73SSaar Raz }
41a0f50d73SSaar Raz struct r2 { };
42a0f50d73SSaar Raz 
43a0f50d73SSaar Raz using r2i = r2<int>;
44a0f50d73SSaar Raz // expected-error@-1 {{constraints not satisfied for class template 'r2' [with T = int]}}
45a0f50d73SSaar Raz 
46a0f50d73SSaar Raz template<typename T> requires requires (T t) {
47a0f50d73SSaar Raz   requires requires {
48a0f50d73SSaar Raz     requires true;
49a0f50d73SSaar Raz   };
50a0f50d73SSaar Raz   requires true;
51a0f50d73SSaar Raz   requires requires {
52a0f50d73SSaar Raz     requires false; // expected-note{{because 'false' evaluated to false}}
53a0f50d73SSaar Raz   };
54a0f50d73SSaar Raz }
55a0f50d73SSaar Raz struct r3 { };
56a0f50d73SSaar Raz 
57a0f50d73SSaar Raz using r3i = r3<int>;
58a0f50d73SSaar Raz // expected-error@-1 {{constraints not satisfied for class template 'r3' [with T = int]}}
59a0f50d73SSaar Raz 
60a0f50d73SSaar Raz template<typename T>
61a0f50d73SSaar Raz struct S { static const int s = T::value; };
62a0f50d73SSaar Raz 
63a0f50d73SSaar Raz template<typename T> requires requires { T::value; S<T>::s; }
64a0f50d73SSaar Raz // expected-note@-1 {{because 'T::value' would be invalid: type 'int' cannot be used prior to '::' because it has no members}}
65a0f50d73SSaar Raz struct r4 { };
66a0f50d73SSaar Raz 
67a0f50d73SSaar Raz using r4i = r4<int>;
68a0f50d73SSaar Raz // expected-error@-1 {{constraints not satisfied for class template 'r4' [with T = int]}}
69*bb78a0b3Sc8ef 
70*bb78a0b3Sc8ef namespace GH109538 {
71*bb78a0b3Sc8ef static_assert(requires(void *t) { t; });
72*bb78a0b3Sc8ef static_assert(requires(void) { 42; });
73*bb78a0b3Sc8ef static_assert(requires(void t) { // expected-error {{argument may not have 'void' type}}
74*bb78a0b3Sc8ef   t;
75*bb78a0b3Sc8ef });
76*bb78a0b3Sc8ef static_assert(requires(void t, int a) {  // expected-error {{'void' must be the first and only parameter if specified}}
77*bb78a0b3Sc8ef   t;
78*bb78a0b3Sc8ef });
79*bb78a0b3Sc8ef static_assert(requires(const void) { // expected-error {{'void' as parameter must not have type qualifiers}}
80*bb78a0b3Sc8ef   42;
81*bb78a0b3Sc8ef });
82*bb78a0b3Sc8ef } // namespace GH109538
83