1 // RUN: %clang_cc1 -std=c++20 -x c++ -Wno-constant-logical-operand -verify %s
2 
3 template<typename T> concept C =
4 sizeof(T) == 4 && !true;      // requires atomic constraints sizeof(T) == 4 and !true
5 
6 template<typename T> concept C2 = sizeof(T); // expected-error{{atomic constraint must be of type 'bool' (found }}
7 
8 template<typename T> struct S {
operator boolS9   constexpr operator bool() const { return true; }
10 };
11 
12 // expected-error@+3{{atomic constraint must be of type 'bool' (found 'S<int>')}}
13 // expected-note@#FINST{{while checking constraint satisfaction}}
14 // expected-note@#FINST{{in instantiation of function template specialization}}
15 template<typename T> requires (S<T>{})
16 void f(T);
17 void f(int);
18 
19 // Ensure this applies to operator && as well.
20 // expected-error@+3{{atomic constraint must be of type 'bool' (found 'S<int>')}}
21 // expected-note@#F2INST{{while checking constraint satisfaction}}
22 // expected-note@#F2INST{{in instantiation of function template specialization}}
23 template<typename T> requires (S<T>{} && true)
24 void f2(T);
25 void f2(int);
26 
27 template<typename T> requires requires {
28   requires S<T>{};
29   // expected-error@-1{{atomic constraint must be of type 'bool' (found 'S<int>')}}
30   // expected-note@-2{{while checking the satisfaction}}
31   // expected-note@-3{{in instantiation of requirement}}
32   // expected-note@-4{{while checking the satisfaction}}
33   // expected-note@-6{{while substituting template arguments}}
34   // expected-note@#F3INST{{while checking constraint satisfaction}}
35   // expected-note@#F3INST{{in instantiation of function template specialization}}
36   //
37 }
38 void f3(T);
39 void f3(int);
40 
41 // Doesn't diagnose, since this is no longer a compound requirement.
42 template<typename T> requires (bool(1 && 2))
43 void f4(T);
44 void f4(int);
45 
g()46 void g() {
47   f(0); // #FINST
48   f2(0); // #F2INST
49   f3(0); // #F3INST
50   f4(0);
51 }
52 
53 template<typename T>
54 auto Nullptr = nullptr;
55 
56 template<typename T> concept NullTy = Nullptr<T>;
57 // expected-error@-1{{atomic constraint must be of type 'bool' (found }}
58 // expected-note@+1{{while checking the satisfaction}}
59 static_assert(NullTy<int>);
60 
61 template<typename T>
62 auto Struct = S<T>{};
63 
64 template<typename T> concept StructTy = Struct<T>;
65 // expected-error@-1{{atomic constraint must be of type 'bool' (found 'S<int>')}}
66 // expected-note@+1{{while checking the satisfaction}}
67 static_assert(StructTy<int>);
68