1 // RUN: %clang_cc1 -std=c++20 -verify %s
2 
3 namespace PR47043 {
4   template<typename T> concept True = true;
5   template<typename ...T> concept AllTrue1 = True<T>; // expected-error {{expression contains unexpanded parameter pack 'T'}}
6   template<typename ...T> concept AllTrue2 = (True<T> && ...);
7   static_assert(AllTrue2<int, float, char>);
8 }
9 
10 namespace PR47025 {
11   template<typename ...T> concept AllAddable1 = requires(T ...t) { (void(t + 1), ...); };
12   template<typename ...T> concept AllAddable2 = (requires(T ...t) { (t + 1); } && ...); // expected-error {{requirement contains unexpanded parameter pack 't'}}
13   template<typename ...T> concept AllAddable3 = (requires(T t) { (t + 1); } && ...);
14   template<typename ...T> concept AllAddable4 = requires(T t) { (t + 1); }; // expected-error {{expression contains unexpanded parameter pack 'T'}}
15   template<typename ...T> concept AllAddable5 = requires(T t) { (void(t + 1), ...); }; // expected-error {{does not contain any unexpanded}}
16   template<typename ...T> concept AllAddable6 = (requires { (T() + 1); } && ...);
17   template<typename ...T> concept AllAddable7 = requires { (T() + 1); }; // expected-error {{expression contains unexpanded parameter pack 'T'}}
18 
19   static_assert(AllAddable1<int, float>);
20   static_assert(AllAddable3<int, float>);
21   static_assert(AllAddable6<int, float>);
22   static_assert(!AllAddable1<int, void>);
23   static_assert(!AllAddable3<int, void>);
24   static_assert(!AllAddable6<int, void>);
25 }
26 
27 namespace PR45699 {
28   template<class> concept C = true; // expected-note 2{{here}}
29   template<class ...Ts> void f1a() requires C<Ts>; // expected-error {{requires clause contains unexpanded parameter pack 'Ts'}}
30   template<class ...Ts> requires C<Ts> void f1b(); // expected-error {{requires clause contains unexpanded parameter pack 'Ts'}}
31   template<class ...Ts> void f2a() requires (C<Ts> && ...);
32   template<class ...Ts> requires (C<Ts> && ...) void f2b();
33   template<class ...Ts> void f3a() requires C<Ts...>; // expected-error {{pack expansion used as argument for non-pack parameter of concept}}
34   template<class ...Ts> requires C<Ts...> void f3b(); // expected-error {{pack expansion used as argument for non-pack parameter of concept}}
35   template<class ...Ts> void f4() {
36     ([] () requires C<Ts> {} ()); // expected-error {{expression contains unexpanded parameter pack 'Ts'}}
37     ([]<int = 0> requires C<Ts> () {} ()); // expected-error {{expression contains unexpanded parameter pack 'Ts'}}
38   }
39   template<class ...Ts> void f5() {
40     ([] () requires C<Ts> {} (), ...);
41     ([]<int = 0> requires C<Ts> () {} (), ...);
42   }
43   void g() {
44     f1a();
45     f1b(); // FIXME: Bad error recovery. expected-error {{undeclared identifier}}
46     f2a();
47     f2b();
48     f3a();
49     f3b(); // FIXME: Bad error recovery. expected-error {{undeclared identifier}}
50     f4();
51     f5();
52   }
53 }
54 
55 namespace P0857R0 {
56   void f() {
57     auto x = []<bool B> requires B {}; // expected-note {{constraints not satisfied}} expected-note {{false}}
58     x.operator()<true>();
59     x.operator()<false>(); // expected-error {{no matching member function}}
60   }
61 
62   // FIXME: This is valid under P0857R0.
63   template<typename T> concept C = true;
64   template<template<typename T> requires C<T> typename U> struct X {}; // expected-error {{requires 'class'}} expected-error 0+{{}}
65   template<typename T> requires C<T> struct Y {};
66   X<Y> xy; // expected-error {{no template named 'X'}}
67 }
68 
69 namespace PR50306 {
70   template<typename T> concept NotInt = sizeof(T) != sizeof(int); // expected-note {{because}}
71   template<typename T> void f() {
72     [](NotInt auto) {}(T()); // expected-error {{no matching function}} expected-note {{constraints not satisfied}} expected-note {{because}}
73   }
74   template void f<char>(); // OK
75   template void f<int>(); // expected-note {{in instantiation of}}
76 }
77 
78 namespace PackInTypeConstraint {
79   template<typename T, typename U> concept C = sizeof(T) == sizeof(int); // expected-note 3{{}}
80 
81   template<typename ...T, C<T> U> void h1(); // expected-error {{type constraint contains unexpanded parameter pack 'T'}}
82   template<typename ...T, C<T> ...U> void h2();
83   template<typename ...T> void h3(C<T> auto); // expected-error {{type constraint contains unexpanded parameter pack 'T'}}
84   template<typename ...T> void h4(C<T> auto...);
85 
86   template<typename ...T> void f1() {
87     []<C<T> U>(U u){}(T()); // expected-error {{unexpanded parameter pack 'T'}}
88   }
89   template<typename ...T> void f2() {
90     ([]<C<T> U>(U u){}(T()), ...); // expected-error {{no match}} expected-note 2{{}}
91   }
92   template void f2<int, int, int>(); // OK
93   template void f2<int, char, double>(); // expected-note {{in instantiation of}}
94   void f3() {
95     ([]<typename ...T, C<T> U>(U u){}(0), // expected-error {{type constraint contains unexpanded parameter pack 'T'}}
96      ...); // expected-error {{does not contain any unexpanded}}
97   }
98 
99   template<typename ...T> void g1() {
100     [](C<T> auto){}(T()); // expected-error {{expression contains unexpanded parameter pack 'T'}}
101   }
102   template<typename ...T> void g2() {
103     ([](C<T> auto){}(T()), ...); // expected-error {{no matching function}} expected-note {{constraints not satisfied}} expected-note {{because}}
104   }
105   template void g2<int, int, int>(); // OK
106   template void g2<int, char, double>(); // expected-note {{in instantiation of}}
107   void g3() {
108     ([]<typename ...T>(C<T> auto){}(1), // expected-error {{type constraint contains unexpanded parameter pack 'T'}}
109      ...); // expected-error {{does not contain any unexpanded}}
110   }
111 
112   template<typename ...T> void g4() {
113     []() -> C<T> auto{ return T(); }(); // expected-error {{expression contains unexpanded parameter pack 'T'}}
114   }
115   template<typename ...T> void g5() {
116     ([]() -> C<T> auto{ // expected-error-re {{deduced type {{.*}} does not satisfy}}
117      return T();
118      }(), ...);
119   }
120   template void g5<int, int, int>(); // OK
121   template void g5<int, char, double>(); // expected-note {{in instantiation of}}
122   void g6() {
123     ([]<typename ...T>() -> C<T> auto{ // expected-error {{declaration type contains unexpanded parameter pack 'T'}}
124      return T(); // expected-error {{expression contains unexpanded parameter pack 'T'}}
125      }(),
126      ...); // expected-error {{does not contain any unexpanded}}
127   }
128 }
129 
130 namespace BuiltinIsConstantEvaluated {
131   // Check that we do all satisfaction and diagnostic checks in a constant context.
132   template<typename T> concept C = __builtin_is_constant_evaluated(); // expected-warning {{always}}
133   static_assert(C<int>);
134 
135   template<typename T> concept D = __builtin_is_constant_evaluated() == true; // expected-warning {{always}}
136   static_assert(D<int>);
137 
138   template<typename T> concept E = __builtin_is_constant_evaluated() == true && // expected-warning {{always}}
139                                    false; // expected-note {{'false' evaluated to false}}
140   static_assert(E<int>); // expected-error {{failed}} expected-note {{because 'int' does not satisfy 'E'}}
141 
142   template<typename T> concept F = __builtin_is_constant_evaluated() == false; // expected-warning {{always}}
143   // expected-note@-1 {{'__builtin_is_constant_evaluated() == false' (1 == 0)}}
144   static_assert(F<int>); // expected-error {{failed}} expected-note {{because 'int' does not satisfy 'F'}}
145 
146   template<typename T> concept G = __builtin_is_constant_evaluated() && // expected-warning {{always}}
147                                    false; // expected-note {{'false' evaluated to false}}
148   static_assert(G<int>); // expected-error {{failed}} expected-note {{because 'int' does not satisfy 'G'}}
149 }
150 
151 namespace NoConstantFolding {
152   // Ensure we use strict constant evaluation rules when checking satisfaction.
153   int n;
154   template <class T> concept C = &n + 3 - 3 == &n; // expected-error {{non-constant expression}} expected-note {{cannot refer to element 3 of non-array object}}
155   static_assert(C<void>); // expected-note {{while checking}}
156 }
157 
158 namespace PR50337 {
159   template <typename T> concept foo = true;
160   template <typename T> concept foo2 = foo<T> && true;
161   void f(foo auto, auto);
162   void f(foo2 auto, auto);
163   void g() { f(1, 2); }
164 }
165 
166 namespace PR50561 {
167   template<typename> concept C = false;
168   template<typename T, typename U> void f(T, U);
169   template<C T, typename U> void f(T, U) = delete;
170   void g() { f(0, 0); }
171 }
172