1 | // RUN: %clang_cc1 -std=c++11 -verify %s |
2 | |
3 | typedef int (*fp)(int); |
4 | int surrogate(int); |
5 | struct Incomplete; // expected-note{{forward declaration of 'Incomplete'}} \ |
6 | // expected-note {{forward declaration of 'Incomplete'}} |
7 | |
8 | struct X { |
9 | X() = default; // expected-note{{candidate constructor not viable: requires 0 arguments, but 1 was provided}} |
10 | X(const X&) = default; // expected-note{{candidate constructor not viable: no known conversion from 'bool' to 'const X' for 1st argument}} |
11 | X(bool b) __attribute__((enable_if(b, "chosen when 'b' is true"))); // expected-note{{candidate disabled: chosen when 'b' is true}} |
12 | |
13 | void f(int n) __attribute__((enable_if(n == 0, "chosen when 'n' is zero"))); |
14 | void f(int n) __attribute__((enable_if(n == 1, "chosen when 'n' is one"))); // expected-note{{member declaration nearly matches}} expected-note 2{{candidate disabled: chosen when 'n' is one}} |
15 | |
16 | void g(int n) __attribute__((enable_if(n == 0, "chosen when 'n' is zero"))); // expected-note{{candidate disabled: chosen when 'n' is zero}} |
17 | |
18 | void h(int n, int m = 0) __attribute__((enable_if(m == 0, "chosen when 'm' is zero"))); // expected-note{{candidate disabled: chosen when 'm' is zero}} |
19 | |
20 | static void s(int n) __attribute__((enable_if(n == 0, "chosen when 'n' is zero"))); // expected-note2{{candidate disabled: chosen when 'n' is zero}} |
21 | |
22 | void conflict(int n) __attribute__((enable_if(n+n == 10, "chosen when 'n' is five"))); // expected-note{{candidate function}} |
23 | void conflict(int n) __attribute__((enable_if(n*2 == 10, "chosen when 'n' is five"))); // expected-note{{candidate function}} |
24 | |
25 | void hidden_by_argument_conversion(Incomplete n, int m = 0) __attribute__((enable_if(m == 10, "chosen when 'm' is ten"))); |
26 | Incomplete hidden_by_incomplete_return_value(int n = 0) __attribute__((enable_if(n == 10, "chosen when 'n' is ten"))); // expected-note{{'hidden_by_incomplete_return_value' declared here}} |
27 | |
28 | operator long() __attribute__((enable_if(true, "chosen on your platform"))); |
29 | operator int() __attribute__((enable_if(false, "chosen on other platform"))); |
30 | |
31 | operator fp() __attribute__((enable_if(false, "never enabled"))) { return surrogate; } // expected-note{{conversion candidate of type 'int (*)(int)'}} // FIXME: the message is not displayed |
32 | }; |
33 | |
34 | void X::f(int n) __attribute__((enable_if(n == 0, "chosen when 'n' is zero"))) // expected-note{{member declaration nearly matches}} expected-note 2{{candidate disabled: chosen when 'n' is zero}} |
35 | { |
36 | } |
37 | |
38 | void X::f(int n) __attribute__((enable_if(n == 2, "chosen when 'n' is two"))) // expected-error{{out-of-line definition of 'f' does not match any declaration in 'X'}} |
39 | { |
40 | } |
41 | |
42 | X x1(true); |
43 | X x2(false); // expected-error{{no matching constructor for initialization of 'X'}} |
44 | |
45 | __attribute__((deprecated)) constexpr int old() { return 0; } // expected-note2{{'old' has been explicitly marked deprecated here}} |
46 | void deprec1(int i) __attribute__((enable_if(old() == 0, "chosen when old() is zero"))); // expected-warning{{'old' is deprecated}} |
47 | void deprec2(int i) __attribute__((enable_if(old() == 0, "chosen when old() is zero"))); // expected-warning{{'old' is deprecated}} |
48 | |
49 | void overloaded(int); |
50 | void overloaded(long); |
51 | |
52 | struct Int { |
53 | constexpr Int(int i) : i(i) { } |
54 | constexpr operator int() const { return i; } |
55 | int i; |
56 | }; |
57 | |
58 | void default_argument(int n, int m = 0) __attribute__((enable_if(m == 0, "chosen when 'm' is zero"))); // expected-note{{candidate disabled: chosen when 'm' is zero}} |
59 | void default_argument_promotion(int n, int m = Int(0)) __attribute__((enable_if(m == 0, "chosen when 'm' is zero"))); // expected-note{{candidate disabled: chosen when 'm' is zero}} |
60 | |
61 | struct Nothing { }; |
62 | template<typename T> void typedep(T t) __attribute__((enable_if(t, ""))); // expected-note{{candidate disabled:}} expected-error{{value of type 'Nothing' is not contextually convertible to 'bool'}} |
63 | template<int N> void valuedep() __attribute__((enable_if(N == 1, ""))); |
64 | |
65 | // FIXME: we skip potential constant expression evaluation on value dependent |
66 | // enable-if expressions |
67 | int not_constexpr(); |
68 | template<int N> void valuedep() __attribute__((enable_if(N == not_constexpr(), ""))); |
69 | |
70 | template <typename T> void instantiationdep() __attribute__((enable_if(sizeof(sizeof(T)) != 0, ""))); |
71 | |
72 | void test() { |
73 | X x; |
74 | x.f(0); |
75 | x.f(1); |
76 | x.f(2); // expected-error{{no matching member function for call to 'f'}} |
77 | x.f(3); // expected-error{{no matching member function for call to 'f'}} |
78 | |
79 | x.g(0); |
80 | x.g(1); // expected-error{{no matching member function for call to 'g'}} |
81 | |
82 | x.h(0); |
83 | x.h(1, 2); // expected-error{{no matching member function for call to 'h'}} |
84 | |
85 | x.s(0); |
86 | x.s(1); // expected-error{{no matching member function for call to 's'}} |
87 | |
88 | X::s(0); |
89 | X::s(1); // expected-error{{no matching member function for call to 's'}} |
90 | |
91 | x.conflict(5); // expected-error{{call to member function 'conflict' is ambiguous}} |
92 | |
93 | x.hidden_by_argument_conversion(10); // expected-error{{argument type 'Incomplete' is incomplete}} |
94 | x.hidden_by_incomplete_return_value(10); // expected-error{{calling 'hidden_by_incomplete_return_value' with incomplete return type 'Incomplete'}} |
95 | |
96 | deprec2(0); |
97 | |
98 | overloaded(x); |
99 | |
100 | default_argument(0); |
101 | default_argument(1, 2); // expected-error{{no matching function for call to 'default_argument'}} |
102 | |
103 | default_argument_promotion(0); |
104 | default_argument_promotion(1, 2); // expected-error{{no matching function for call to 'default_argument_promotion'}} |
105 | |
106 | int i = x(1); // expected-error{{no matching function for call to object of type 'X'}} |
107 | |
108 | Nothing n; |
109 | typedep(0); // expected-error{{no matching function for call to 'typedep'}} |
110 | typedep(1); |
111 | typedep(n); // expected-note{{in instantiation of function template specialization 'typedep<Nothing>' requested here}} |
112 | } |
113 | |
114 | template <typename T> class C { |
115 | void f() __attribute__((enable_if(T::expr == 0, ""))) {} |
116 | void g() { f(); } |
117 | }; |
118 | |
119 | int fn3(bool b) __attribute__((enable_if(b, ""))); // FIXME: This test should net 0 error messages. |
120 | template <class T> void test3() { |
121 | fn3(sizeof(T) == 1); // expected-error{{no matching function for call to 'fn3'}} expected-note@-2{{candidate disabled}} |
122 | } |
123 | |
124 | template <typename T> |
125 | struct Y { |
126 | T h(int n, int m = 0) __attribute__((enable_if(m == 0, "chosen when 'm' is zero"))); // expected-note{{candidate disabled: chosen when 'm' is zero}} |
127 | }; |
128 | |
129 | void test4() { |
130 | Y<int> y; |
131 | |
132 | int t0 = y.h(0); |
133 | int t1 = y.h(1, 2); // expected-error{{no matching member function for call to 'h'}} |
134 | } |
135 | |
136 | // FIXME: issue an error (without instantiation) because ::h(T()) is not |
137 | // convertible to bool, because return types aren't overloadable. |
138 | void h(int); |
139 | template <typename T> void outer() { |
140 | void local_function() __attribute__((enable_if(::h(T()), ""))); |
141 | local_function(); // expected-error{{no matching function for call to 'local_function'}} expected-note@-1{{candidate disabled}} |
142 | }; |
143 | |
144 | namespace PR20988 { |
145 | struct Integer { |
146 | Integer(int); |
147 | }; |
148 | |
149 | int fn1(const Integer &) __attribute__((enable_if(true, ""))); |
150 | template <class T> void test1() { |
151 | int &expr = T::expr(); |
152 | fn1(expr); |
153 | } |
154 | |
155 | int fn2(const Integer &) __attribute__((enable_if(false, ""))); // expected-note{{candidate disabled}} |
156 | template <class T> void test2() { |
157 | int &expr = T::expr(); |
158 | fn2(expr); // expected-error{{no matching function for call to 'fn2'}} |
159 | } |
160 | |
161 | int fn3(bool b) __attribute__((enable_if(b, ""))); // FIXME: This test should net 0 error messages. |
162 | template <class T> void test3() { |
163 | fn3(sizeof(T) == 1); // expected-error{{no matching function for call to 'fn3'}} expected-note@-2{{candidate disabled}} |
164 | } |
165 | } |
166 | |
167 | namespace FnPtrs { |
168 | int ovlFoo(int m) __attribute__((enable_if(m > 0, ""))); |
169 | int ovlFoo(int m); |
170 | |
171 | void test() { |
172 | // Assignment gives us a different code path than declarations, and `&foo` |
173 | // gives us a different code path than `foo` |
174 | int (*p)(int) = ovlFoo; |
175 | int (*p2)(int) = &ovlFoo; |
176 | int (*a)(int); |
177 | a = ovlFoo; |
178 | a = &ovlFoo; |
179 | } |
180 | |
181 | int ovlBar(int) __attribute__((enable_if(true, ""))); |
182 | int ovlBar(int m) __attribute__((enable_if(false, ""))); |
183 | void test2() { |
184 | int (*p)(int) = ovlBar; |
185 | int (*p2)(int) = &ovlBar; |
186 | int (*a)(int); |
187 | a = ovlBar; |
188 | a = &ovlBar; |
189 | } |
190 | |
191 | int ovlConflict(int m) __attribute__((enable_if(true, ""))); |
192 | int ovlConflict(int m) __attribute__((enable_if(1, ""))); |
193 | void test3() { |
194 | int (*p)(int) = ovlConflict; // expected-error{{address of overloaded function 'ovlConflict' is ambiguous}} expected-note@191{{candidate function}} expected-note@192{{candidate function}} |
195 | int (*p2)(int) = &ovlConflict; // expected-error{{address of overloaded function 'ovlConflict' is ambiguous}} expected-note@191{{candidate function}} expected-note@192{{candidate function}} |
196 | int (*a)(int); |
197 | a = ovlConflict; // expected-error{{assigning to 'int (*)(int)' from incompatible type '<overloaded function type>'}} expected-note@191{{candidate function}} expected-note@192{{candidate function}} |
198 | a = &ovlConflict; // expected-error{{assigning to 'int (*)(int)' from incompatible type '<overloaded function type>'}} expected-note@191{{candidate function}} expected-note@192{{candidate function}} |
199 | } |
200 | |
201 | template <typename T> |
202 | T templated(T m) __attribute__((enable_if(true, ""))) { return T(); } |
203 | template <typename T> |
204 | T templated(T m) __attribute__((enable_if(false, ""))) { return T(); } |
205 | void test4() { |
206 | int (*p)(int) = templated<int>; |
207 | int (*p2)(int) = &templated<int>; |
208 | int (*a)(int); |
209 | a = templated<int>; |
210 | a = &templated<int>; |
211 | } |
212 | |
213 | template <typename T> |
214 | T templatedBar(T m) __attribute__((enable_if(m > 0, ""))) { return T(); } |
215 | void test5() { |
216 | int (*p)(int) = templatedBar<int>; // expected-error{{address of overloaded function 'templatedBar' does not match required type 'int (int)'}} expected-note@214{{candidate function made ineligible by enable_if}} |
217 | int (*p2)(int) = &templatedBar<int>; // expected-error{{address of overloaded function 'templatedBar' does not match required type 'int (int)'}} expected-note@214{{candidate function made ineligible by enable_if}} |
218 | int (*a)(int); |
219 | a = templatedBar<int>; // expected-error{{assigning to 'int (*)(int)' from incompatible type '<overloaded function type>'}} expected-note@214{{candidate function made ineligible by enable_if}} |
220 | a = &templatedBar<int>; // expected-error{{assigning to 'int (*)(int)' from incompatible type '<overloaded function type>'}} expected-note@214{{candidate function made ineligible by enable_if}} |
221 | } |
222 | |
223 | template <typename T> |
224 | T templatedConflict(T m) __attribute__((enable_if(false, ""))) { return T(); } |
225 | template <typename T> |
226 | T templatedConflict(T m) __attribute__((enable_if(true, ""))) { return T(); } |
227 | template <typename T> |
228 | T templatedConflict(T m) __attribute__((enable_if(1, ""))) { return T(); } |
229 | void test6() { |
230 | int (*p)(int) = templatedConflict<int>; // expected-error{{address of overloaded function 'templatedConflict' is ambiguous}} expected-note@224{{candidate function made ineligible by enable_if}} expected-note@226{{candidate function}} expected-note@228{{candidate function}} |
231 | int (*p0)(int) = &templatedConflict<int>; // expected-error{{address of overloaded function 'templatedConflict' is ambiguous}} expected-note@224{{candidate function made ineligible by enable_if}} expected-note@226{{candidate function}} expected-note@228{{candidate function}} |
232 | int (*a)(int); |
233 | a = templatedConflict<int>; // expected-error{{assigning to 'int (*)(int)' from incompatible type '<overloaded function type>'}} expected-note@226{{candidate function}} expected-note@228{{candidate function}} |
234 | a = &templatedConflict<int>; // expected-error{{assigning to 'int (*)(int)' from incompatible type '<overloaded function type>'}} expected-note@226{{candidate function}} expected-note@228{{candidate function}} |
235 | } |
236 | |
237 | int ovlNoCandidate(int m) __attribute__((enable_if(false, ""))); |
238 | int ovlNoCandidate(int m) __attribute__((enable_if(0, ""))); |
239 | void test7() { |
240 | int (*p)(int) = ovlNoCandidate; // expected-error{{address of overloaded function 'ovlNoCandidate' does not match required type}} expected-note@237{{made ineligible by enable_if}} expected-note@238{{made ineligible by enable_if}} |
241 | int (*p2)(int) = &ovlNoCandidate; // expected-error{{address of overloaded function 'ovlNoCandidate' does not match required type}} expected-note@237{{made ineligible by enable_if}} expected-note@238{{made ineligible by enable_if}} |
242 | int (*a)(int); |
243 | a = ovlNoCandidate; // expected-error{{assigning to 'int (*)(int)' from incompatible type '<overloaded function type>'}} expected-note@237{{made ineligible by enable_if}} expected-note@238{{made ineligible by enable_if}} |
244 | a = &ovlNoCandidate; // expected-error{{assigning to 'int (*)(int)' from incompatible type '<overloaded function type>'}} expected-note@237{{made ineligible by enable_if}} expected-note@238{{made ineligible by enable_if}} |
245 | } |
246 | |
247 | int noOvlNoCandidate(int m) __attribute__((enable_if(false, ""))); |
248 | void test8() { |
249 | int (*p)(int) = noOvlNoCandidate; // expected-error{{cannot take address of function 'noOvlNoCandidate' because it has one or more non-tautological enable_if conditions}} |
250 | int (*p2)(int) = &noOvlNoCandidate; // expected-error{{cannot take address of function 'noOvlNoCandidate' because it has one or more non-tautological enable_if conditions}} |
251 | int (*a)(int); |
252 | a = noOvlNoCandidate; // expected-error{{cannot take address of function 'noOvlNoCandidate' because it has one or more non-tautological enable_if conditions}} |
253 | a = &noOvlNoCandidate; // expected-error{{cannot take address of function 'noOvlNoCandidate' because it has one or more non-tautological enable_if conditions}} |
254 | } |
255 | } |
256 | |
257 | namespace casting { |
258 | using VoidFnTy = void (*)(); |
259 | |
260 | void foo(void *c) __attribute__((enable_if(0, ""))); |
261 | void foo(int *c) __attribute__((enable_if(c, ""))); |
262 | void foo(char *c) __attribute__((enable_if(1, ""))); |
263 | |
264 | void testIt() { |
265 | auto A = reinterpret_cast<VoidFnTy>(foo); |
266 | auto AAmp = reinterpret_cast<VoidFnTy>(&foo); |
267 | |
268 | using VoidFooTy = void (*)(void *); |
269 | auto B = reinterpret_cast<VoidFooTy>(foo); |
270 | auto BAmp = reinterpret_cast<VoidFooTy>(&foo); |
271 | |
272 | using IntFooTy = void (*)(int *); |
273 | auto C = reinterpret_cast<IntFooTy>(foo); |
274 | auto CAmp = reinterpret_cast<IntFooTy>(&foo); |
275 | |
276 | using CharFooTy = void (*)(void *); |
277 | auto D = reinterpret_cast<CharFooTy>(foo); |
278 | auto DAmp = reinterpret_cast<CharFooTy>(&foo); |
279 | } |
280 | |
281 | void testItCStyle() { |
282 | auto A = (VoidFnTy)foo; |
283 | auto AAmp = (VoidFnTy)&foo; |
284 | |
285 | using VoidFooTy = void (*)(void *); |
286 | auto B = (VoidFooTy)foo; |
287 | auto BAmp = (VoidFooTy)&foo; |
288 | |
289 | using IntFooTy = void (*)(int *); |
290 | auto C = (IntFooTy)foo; |
291 | auto CAmp = (IntFooTy)&foo; |
292 | |
293 | using CharFooTy = void (*)(void *); |
294 | auto D = (CharFooTy)foo; |
295 | auto DAmp = (CharFooTy)&foo; |
296 | } |
297 | } |
298 | |
299 | namespace casting_templates { |
300 | template <typename T> void foo(T) {} // expected-note 4 {{candidate function}} |
301 | |
302 | void foo(int *c) __attribute__((enable_if(c, ""))); //expected-note 4 {{candidate function}} |
303 | void foo(char *c) __attribute__((enable_if(c, ""))); //expected-note 4 {{candidate function}} |
304 | |
305 | void testIt() { |
306 | using IntFooTy = void (*)(int *); |
307 | auto A = reinterpret_cast<IntFooTy>(foo); // expected-error{{reinterpret_cast cannot resolve overloaded function 'foo' to type}} |
308 | auto ARef = reinterpret_cast<IntFooTy>(&foo); // expected-error{{reinterpret_cast cannot resolve overloaded function 'foo' to type}} |
309 | auto AExplicit = reinterpret_cast<IntFooTy>(foo<int*>); |
310 | |
311 | using CharFooTy = void (*)(char *); |
312 | auto B = reinterpret_cast<CharFooTy>(foo); // expected-error{{reinterpret_cast cannot resolve overloaded function 'foo' to type}} |
313 | auto BRef = reinterpret_cast<CharFooTy>(&foo); // expected-error{{reinterpret_cast cannot resolve overloaded function 'foo' to type}} |
314 | auto BExplicit = reinterpret_cast<CharFooTy>(foo<char*>); |
315 | } |
316 | |
317 | void testItCStyle() { |
318 | // constexpr is usable here because all of these should become static_casts. |
319 | using IntFooTy = void (*)(int *); |
320 | constexpr auto A = (IntFooTy)foo; |
321 | constexpr auto ARef = (IntFooTy)&foo; |
322 | constexpr auto AExplicit = (IntFooTy)foo<int*>; |
323 | |
324 | using CharFooTy = void (*)(char *); |
325 | constexpr auto B = (CharFooTy)foo; |
326 | constexpr auto BRef = (CharFooTy)&foo; |
327 | constexpr auto BExplicit = (CharFooTy)foo<char*>; |
328 | |
329 | static_assert(A == ARef && ARef == AExplicit, ""); |
330 | static_assert(B == BRef && BRef == BExplicit, ""); |
331 | } |
332 | } |
333 | |
334 | namespace multiple_matches { |
335 | using NoMatchTy = void (*)(); |
336 | |
337 | void foo(float *c); //expected-note 4 {{candidate function}} |
338 | void foo(int *c) __attribute__((enable_if(1, ""))); //expected-note 4 {{candidate function}} |
339 | void foo(char *c) __attribute__((enable_if(1, ""))); //expected-note 4 {{candidate function}} |
340 | |
341 | void testIt() { |
342 | auto A = reinterpret_cast<NoMatchTy>(foo); // expected-error{{reinterpret_cast cannot resolve overloaded function 'foo' to type}} |
343 | auto ARef = reinterpret_cast<NoMatchTy>(&foo); // expected-error{{reinterpret_cast cannot resolve overloaded function 'foo' to type}} |
344 | |
345 | auto C = (NoMatchTy)foo; // expected-error{{address of overloaded function 'foo' does not match required type 'void ()'}} |
346 | auto CRef = (NoMatchTy)&foo; // expected-error{{address of overloaded function 'foo' does not match required type 'void ()'}} |
347 | } |
348 | } |
349 | |
350 | namespace PR27122 { |
351 | // (slightly reduced) code that motivated the bug... |
352 | namespace ns { |
353 | void Function(int num) |
354 | __attribute__((enable_if(num != 0, ""))); |
355 | void Function(int num, int a0) |
356 | __attribute__((enable_if(num != 1, ""))); |
357 | } // namespace ns |
358 | |
359 | using ns::Function; // expected-note 3{{declared here}} |
360 | void Run() { |
361 | Functioon(0); // expected-error{{use of undeclared identifier}} expected-error{{too few arguments}} |
362 | Functioon(0, 1); // expected-error{{use of undeclared identifier}} |
363 | Functioon(0, 1, 2); // expected-error{{use of undeclared identifier}} |
364 | } |
365 | |
366 | // Extra tests |
367 | void regularEnableIf(int a) __attribute__((enable_if(a, ""))); // expected-note 3{{declared here}} expected-note 3{{candidate function not viable}} |
368 | void runRegularEnableIf() { |
369 | regularEnableIf(0, 2); // expected-error{{no matching function}} |
370 | regularEnableIf(1, 2); // expected-error{{no matching function}} |
371 | regularEnableIf(); // expected-error{{no matching function}} |
372 | |
373 | // Test without getting overload resolution involved |
374 | ::PR27122::regularEnableIf(0, 2); // expected-error{{too many arguments}} |
375 | ::PR27122::regularEnableIf(1, 2); // expected-error{{too many arguments}} |
376 | ::PR27122::regularEnableIf(); // expected-error{{too few arguments}} |
377 | } |
378 | |
379 | struct Foo { |
380 | void bar(int i) __attribute__((enable_if(i, ""))); // expected-note 2{{declared here}} |
381 | }; |
382 | |
383 | void runFoo() { |
384 | Foo f; |
385 | f.bar(); // expected-error{{too few arguments}} |
386 | f.bar(1, 2); // expected-error{{too many arguments}} |
387 | } |
388 | } |
389 | |
390 | // Ideally, we should be able to handle value-dependent expressions sanely. |
391 | // Sadly, that isn't the case at the moment. |
392 | namespace dependent { |
393 | int error(int N) __attribute__((enable_if(N, ""))); // expected-note{{candidate disabled}} |
394 | int error(int N) __attribute__((enable_if(!N, ""))); // expected-note{{candidate disabled}} |
395 | template <int N> int callUnavailable() { |
396 | return error(N); // expected-error{{no matching function for call to 'error'}} |
397 | } |
398 | |
399 | constexpr int noError(int N) __attribute__((enable_if(N, ""))) { return -1; } |
400 | constexpr int noError(int N) __attribute__((enable_if(!N, ""))) { return -1; } |
401 | constexpr int noError(int N) { return 0; } |
402 | |
403 | template <int N> |
404 | constexpr int callNoError() { return noError(N); } |
405 | static_assert(callNoError<0>() == 0, ""); |
406 | static_assert(callNoError<1>() == 0, ""); |
407 | |
408 | template <int N> constexpr int templated() __attribute__((enable_if(N, ""))) { |
409 | return 1; |
410 | } |
411 | |
412 | constexpr int A = templated<0>(); // expected-error{{no matching function for call to 'templated'}} expected-note@-4{{candidate disabled}} |
413 | static_assert(templated<1>() == 1, ""); |
414 | |
415 | template <int N> constexpr int callTemplated() { return templated<N>(); } |
416 | |
417 | constexpr int B = 10 + // the carat for the error should be pointing to the problematic call (on the next line), not here. |
418 | callTemplated<0>(); // expected-error{{initialized by a constant expression}} expected-error@-3{{no matching function for call to 'templated'}} expected-note{{in instantiation of function template}} expected-note@-10{{candidate disabled}} |
419 | static_assert(callTemplated<1>() == 1, ""); |
420 | } |
421 | |
422 | namespace variadic { |
423 | void foo(int a, int b = 0, ...) __attribute__((enable_if(a && b, ""))); // expected-note 6{{disabled}} |
424 | |
425 | void testFoo() { |
426 | foo(1, 1); |
427 | foo(1, 1, 2); |
428 | foo(1, 1, 2, 3); |
429 | |
430 | foo(1, 0); // expected-error{{no matching}} |
431 | foo(1, 0, 2); // expected-error{{no matching}} |
432 | foo(1, 0, 2, 3); // expected-error{{no matching}} |
433 | |
434 | int m; |
435 | foo(1, 1); |
436 | foo(1, 1, m); |
437 | foo(1, 1, m, 3); |
438 | |
439 | foo(1, 0); // expected-error{{no matching}} |
440 | foo(1, 0, m); // expected-error{{no matching}} |
441 | foo(1, 0, m, 3); // expected-error{{no matching}} |
442 | } |
443 | } |
444 | |
445 | // Tests that we emit errors at the point of the method call, rather than the |
446 | // beginning of the expression that happens to be a member call. |
447 | namespace member_loc { |
448 | struct Foo { void bar() __attribute__((enable_if(0, ""))); }; // expected-note{{disabled}} |
449 | void testFoo() { |
450 | Foo() |
451 | .bar(); // expected-error{{no matching member function}} |
452 | } |
453 | } |
454 | |
455 | // Prior bug: we wouldn't properly convert conditions to bools when |
456 | // instantiating templates in some cases. |
457 | namespace template_instantiation { |
458 | template <typename T> |
459 | struct Foo { |
460 | void bar(int a) __attribute__((enable_if(a, ""))); // expected-note{{disabled}} |
461 | }; |
462 | |
463 | void runFoo() { |
464 | Foo<double>().bar(0); // expected-error{{no matching}} |
465 | Foo<double>().bar(1); |
466 | } |
467 | } |
468 | |
469 | namespace instantiate_constexpr_in_enable_if { |
470 | template<typename T> struct X { |
471 | static constexpr bool ok() { return true; } |
472 | void f() __attribute__((enable_if(ok(), ""))); |
473 | }; |
474 | void g() { X<int>().f(); } |
475 | } |
476 | |
477 | namespace PR31934 { |
478 | int foo(int a) __attribute__((enable_if(a, ""))); |
479 | int runFn(int (&)(int)); |
480 | |
481 | void run() { |
482 | { |
483 | int (&bar)(int) = foo; // expected-error{{cannot take address of function 'foo'}} |
484 | int baz = runFn(foo); // expected-error{{cannot take address of function 'foo'}} |
485 | } |
486 | |
487 | { |
488 | int (&bar)(int) = (foo); // expected-error{{cannot take address of function 'foo'}} |
489 | int baz = runFn((foo)); // expected-error{{cannot take address of function 'foo'}} |
490 | } |
491 | |
492 | { |
493 | int (&bar)(int) = static_cast<int (&)(int)>(foo); // expected-error{{cannot take address of function 'foo'}} |
494 | int baz = runFn(static_cast<int (&)(int)>(foo)); // expected-error{{cannot take address of function 'foo'}} |
495 | } |
496 | |
497 | { |
498 | int (&bar)(int) = static_cast<int (&)(int)>((foo)); // expected-error{{cannot take address of function 'foo'}} |
499 | int baz = runFn(static_cast<int (&)(int)>((foo))); // expected-error{{cannot take address of function 'foo'}} |
500 | } |
501 | } |
502 | } |
503 | |
504 | namespace TypeOfFn { |
505 | template <typename T, typename U> |
506 | struct is_same; |
507 | |
508 | template <typename T> struct is_same<T, T> { |
509 | enum { value = 1 }; |
510 | }; |
511 | |
512 | void foo(int a) __attribute__((enable_if(a, ""))); |
513 | void foo(float a) __attribute__((enable_if(1, ""))); |
514 | |
515 | static_assert(is_same<__typeof__(foo)*, decltype(&foo)>::value, ""); |
516 | } |
517 | |
518 | namespace InConstantContext { |
519 | void foo(const char *s) __attribute__((enable_if(((void)__builtin_constant_p(*s), true), "trap"))) {} |
520 | |
521 | void test() { |
522 | InConstantContext::foo("abc"); |
523 | } |
524 | } // namespace InConstantContext |
525 | |