xref: /llvm-project/clang/test/SemaTemplate/concepts-recovery-expr.cpp (revision 141de749597c7b59ebe2c4aa7ee573d124dc903c)
1 // RUN: %clang_cc1 -std=c++20 -verify %s
2 
3 // expected-error@+1{{use of undeclared identifier 'b'}}
4 constexpr bool CausesRecoveryExpr = b;
5 
6 template<typename T>
7 concept ReferencesCRE = CausesRecoveryExpr;
8 
9 template<typename T> requires CausesRecoveryExpr // #NVC1REQ
NoViableCands1()10 void NoViableCands1(){} // #NVC1
11 
12 template<typename T> requires ReferencesCRE<T> // #NVC2REQ
NoViableCands2()13 void NoViableCands2(){} // #NVC2
14 
15 template<ReferencesCRE T> // #NVC3REQ
NoViableCands3()16 void NoViableCands3(){} // #NVC3
17 
NVCUse()18 void NVCUse() {
19   NoViableCands1<int>();
20   // expected-error@-1 {{no matching function for call to 'NoViableCands1'}}
21   // expected-note@#NVC1{{candidate template ignored: constraints not satisfied}}
22   // expected-note@#NVC1REQ{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}}
23 
24   NoViableCands2<int>();
25   // expected-error@-1 {{no matching function for call to 'NoViableCands2'}}
26   // expected-note@#NVC2{{candidate template ignored: constraints not satisfied}}
27   // expected-note@#NVC2REQ{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}}
28   NoViableCands3<int>();
29   // expected-error@-1 {{no matching function for call to 'NoViableCands3'}}
30   // expected-note@#NVC3{{candidate template ignored: constraints not satisfied}}
31   // expected-note@#NVC3REQ{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}}
32 }
33 
34 template<typename T> requires CausesRecoveryExpr // #OVC1REQ
OtherViableCands1()35 void OtherViableCands1(){} // #OVC1
36 
37 template<typename T>
OtherViableCands1()38 void OtherViableCands1(){} // #OVC1_ALT
39 
40 template<typename T> requires ReferencesCRE<T> // #OVC2REQ
OtherViableCands2()41 void OtherViableCands2(){} // #OVC2
42 
43 template<typename T>
OtherViableCands2()44 void OtherViableCands2(){} // #OVC2_ALT
45 
46 template<ReferencesCRE T> // #OVC3REQ
OtherViableCands3()47 void OtherViableCands3(){} // #OVC3
48 template<typename T>
OtherViableCands3()49 void OtherViableCands3(){} // #OVC3_ALT
50 
OVCUse()51 void OVCUse() {
52   OtherViableCands1<int>();
53   // expected-error@-1 {{no matching function for call to 'OtherViableCands1'}}
54   // expected-note@#OVC1_ALT {{candidate function}}
55   // expected-note@#OVC1 {{candidate template ignored: constraints not satisfied}}
56   // expected-note@#OVC1REQ{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}}
57   OtherViableCands2<int>();
58   // expected-error@-1 {{no matching function for call to 'OtherViableCands2'}}
59   // expected-note@#OVC2_ALT {{candidate function}}
60   // expected-note@#OVC2 {{candidate template ignored: constraints not satisfied}}
61   // expected-note@#OVC2REQ{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}}
62   OtherViableCands3<int>();
63   // expected-error@-1 {{no matching function for call to 'OtherViableCands3'}}
64   // expected-note@#OVC3_ALT {{candidate function}}
65   // expected-note@#OVC3 {{candidate template ignored: constraints not satisfied}}
66   // expected-note@#OVC3REQ{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}}
67 }
68 
69 template<typename T> requires CausesRecoveryExpr // #OBNVC1REQ
OtherBadNoViableCands1()70 void OtherBadNoViableCands1(){} // #OBNVC1
71 
72 template<typename T> requires false // #OBNVC1REQ_ALT
OtherBadNoViableCands1()73 void OtherBadNoViableCands1(){} // #OBNVC1_ALT
74 
75 template<typename T> requires ReferencesCRE<T> // #OBNVC2REQ
OtherBadNoViableCands2()76 void OtherBadNoViableCands2(){} // #OBNVC2
77 
78 template<typename T> requires false// #OBNVC2REQ_ALT
OtherBadNoViableCands2()79 void OtherBadNoViableCands2(){} // #OBNVC2_ALT
80 
81 template<ReferencesCRE T> // #OBNVC3REQ
OtherBadNoViableCands3()82 void OtherBadNoViableCands3(){} // #OBNVC3
83 template<typename T> requires false // #OBNVC3REQ_ALT
OtherBadNoViableCands3()84 void OtherBadNoViableCands3(){} // #OBNVC3_ALT
85 
OBNVCUse()86 void OBNVCUse() {
87   OtherBadNoViableCands1<int>();
88   // expected-error@-1 {{no matching function for call to 'OtherBadNoViableCands1'}}
89   // expected-note@#OBNVC1_ALT {{candidate template ignored: constraints not satisfied}}
90   // expected-note@#OBNVC1REQ_ALT {{because 'false' evaluated to false}}
91   // expected-note@#OBNVC1 {{candidate template ignored: constraints not satisfied}}
92   // expected-note@#OBNVC1REQ{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}}
93   OtherBadNoViableCands2<int>();
94   // expected-error@-1 {{no matching function for call to 'OtherBadNoViableCands2'}}
95   // expected-note@#OBNVC2_ALT {{candidate template ignored: constraints not satisfied}}
96   // expected-note@#OBNVC2REQ_ALT {{because 'false' evaluated to false}}
97   // expected-note@#OBNVC2 {{candidate template ignored: constraints not satisfied}}
98   // expected-note@#OBNVC2REQ{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}}
99   OtherBadNoViableCands3<int>();
100   // expected-error@-1 {{no matching function for call to 'OtherBadNoViableCands3'}}
101   // expected-note@#OBNVC3_ALT {{candidate template ignored: constraints not satisfied}}
102   // expected-note@#OBNVC3REQ_ALT {{because 'false' evaluated to false}}
103   // expected-note@#OBNVC3 {{candidate template ignored: constraints not satisfied}}
104   // expected-note@#OBNVC3REQ{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}}
105 }
106 
107 
108 // Same tests with member functions.
109 struct OVC {
110 template<typename T> requires CausesRecoveryExpr // #MEMOVC1REQ
OtherViableCands1OVC111 void OtherViableCands1(){} // #MEMOVC1
112 
113 template<typename T>
OtherViableCands1OVC114 void OtherViableCands1(){} // #MEMOVC1_ALT
115 
116 template<typename T> requires ReferencesCRE<T> // #MEMOVC2REQ
OtherViableCands2OVC117 void OtherViableCands2(){} // #MEMOVC2
118 
119 template<typename T>
OtherViableCands2OVC120 void OtherViableCands2(){} // #MEMOVC2_ALT
121 
122 template<ReferencesCRE T> // #MEMOVC3REQ
OtherViableCands3OVC123 void OtherViableCands3(){} // #MEMOVC3
124 template<typename T>
OtherViableCands3OVC125 void OtherViableCands3(){} // #MEMOVC3_ALT
126 };
127 
MemOVCUse()128 void MemOVCUse() {
129   OVC S;
130   S.OtherViableCands1<int>();
131   // expected-error@-1 {{no matching member function for call to 'OtherViableCands1'}}
132   // expected-note@#MEMOVC1_ALT {{candidate function}}
133   // expected-note@#MEMOVC1 {{candidate template ignored: constraints not satisfied}}
134   // expected-note@#MEMOVC1REQ{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}}
135   S.OtherViableCands2<int>();
136   // expected-error@-1 {{no matching member function for call to 'OtherViableCands2'}}
137   // expected-note@#MEMOVC2_ALT {{candidate function}}
138   // expected-note@#MEMOVC2 {{candidate template ignored: constraints not satisfied}}
139   // expected-note@#MEMOVC2REQ{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}}
140   S.OtherViableCands3<int>();
141   // expected-error@-1 {{no matching member function for call to 'OtherViableCands3'}}
142   // expected-note@#MEMOVC3_ALT {{candidate function}}
143   // expected-note@#MEMOVC3 {{candidate template ignored: constraints not satisfied}}
144   // expected-note@#MEMOVC3REQ{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}}
145 }
146 
147 struct StaticOVC {
148 template<typename T> requires CausesRecoveryExpr // #SMEMOVC1REQ
OtherViableCands1StaticOVC149 static void OtherViableCands1(){} // #SMEMOVC1
150 
151 template<typename T>
OtherViableCands1StaticOVC152 static void OtherViableCands1(){} // #SMEMOVC1_ALT
153 
154 template<typename T> requires ReferencesCRE<T> // #SMEMOVC2REQ
OtherViableCands2StaticOVC155 static void OtherViableCands2(){} // #SMEMOVC2
156 
157 template<typename T>
OtherViableCands2StaticOVC158 static void OtherViableCands2(){} // #SMEMOVC2_ALT
159 
160 template<ReferencesCRE T> // #SMEMOVC3REQ
OtherViableCands3StaticOVC161 static void OtherViableCands3(){} // #SMEMOVC3
162 template<typename T>
OtherViableCands3StaticOVC163 static void OtherViableCands3(){} // #SMEMOVC3_ALT
164 };
165 
StaticMemOVCUse()166 void StaticMemOVCUse() {
167   StaticOVC::OtherViableCands1<int>();
168   // expected-error@-1 {{no matching function for call to 'OtherViableCands1'}}
169   // expected-note@#SMEMOVC1_ALT {{candidate function}}
170   // expected-note@#SMEMOVC1 {{candidate template ignored: constraints not satisfied}}
171   // expected-note@#SMEMOVC1REQ{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}}
172   StaticOVC::OtherViableCands2<int>();
173   // expected-error@-1 {{no matching function for call to 'OtherViableCands2'}}
174   // expected-note@#SMEMOVC2_ALT {{candidate function}}
175   // expected-note@#SMEMOVC2 {{candidate template ignored: constraints not satisfied}}
176   // expected-note@#SMEMOVC2REQ{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}}
177   StaticOVC::OtherViableCands3<int>();
178   // expected-error@-1 {{no matching function for call to 'OtherViableCands3'}}
179   // expected-note@#SMEMOVC3_ALT {{candidate function}}
180   // expected-note@#SMEMOVC3 {{candidate template ignored: constraints not satisfied}}
181   // expected-note@#SMEMOVC3REQ{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}}
182 }
183 
184 namespace GH58548 {
185 
186 template <class, class> struct formatter; // #primary-template
187 template <class, class> struct basic_format_context {};
188 
189 template <typename CharType>
190 concept has_format_function =
191     format(basic_format_context<CharType, CharType>());
192 
193 template <typename ValueType, typename CharType>
194   requires has_format_function<CharType>
195 struct formatter<ValueType, CharType> {
196   template <typename OutputIt>
197   CharType format(basic_format_context<OutputIt, CharType>);
198 };
199 
handle_replacement_field(Ctx arg)200 template <class Ctx> int handle_replacement_field(Ctx arg) {
201   formatter<decltype(arg), int> ctx; // expected-error {{implicit instantiation of undefined template}}
202   return 0;
203 }
204 
205 int x = handle_replacement_field(0);
206 // expected-note@-1 {{template specialization 'GH58548::handle_replacement_field<int>' requested here}}
207 // expected-note@#primary-template {{is declared here}}
208 
209 } // GH58548
210