blob: 5695cab9a27e5b991366f8e74abeb23d9a31d5ff [file] [log] [blame]
Richard Smithd8a52a72014-11-12 01:43:45 +00001// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
Richard Smith593d6a12016-12-23 01:30:39 +00002// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++1z
Douglas Gregoradee3e32009-11-11 23:06:43 +00003
4// Template argument deduction with template template parameters.
5template<typename T, template<T> class A>
6struct X0 {
7 static const unsigned value = 0;
8};
9
10template<template<int> class A>
11struct X0<int, A> {
12 static const unsigned value = 1;
13};
14
15template<int> struct X0i;
16template<long> struct X0l;
17int array_x0a[X0<long, X0l>::value == 0? 1 : -1];
18int array_x0b[X0<int, X0i>::value == 1? 1 : -1];
19
20template<typename T, typename U>
21struct is_same {
22 static const bool value = false;
23};
24
25template<typename T>
26struct is_same<T, T> {
27 static const bool value = true;
28};
29
30template<typename T> struct allocator { };
31template<typename T, typename Alloc = allocator<T> > struct vector {};
32
33// Fun with meta-lambdas!
34struct _1 {};
35struct _2 {};
36
37// Replaces all occurrences of _1 with Arg1 and _2 with Arg2 in T.
38template<typename T, typename Arg1, typename Arg2>
39struct Replace {
40 typedef T type;
41};
42
43// Replacement of the whole type.
44template<typename Arg1, typename Arg2>
45struct Replace<_1, Arg1, Arg2> {
46 typedef Arg1 type;
47};
48
49template<typename Arg1, typename Arg2>
50struct Replace<_2, Arg1, Arg2> {
51 typedef Arg2 type;
52};
53
54// Replacement through cv-qualifiers
55template<typename T, typename Arg1, typename Arg2>
56struct Replace<const T, Arg1, Arg2> {
57 typedef typename Replace<T, Arg1, Arg2>::type const type;
58};
59
60// Replacement of templates
61template<template<typename> class TT, typename T1, typename Arg1, typename Arg2>
62struct Replace<TT<T1>, Arg1, Arg2> {
63 typedef TT<typename Replace<T1, Arg1, Arg2>::type> type;
64};
65
66template<template<typename, typename> class TT, typename T1, typename T2,
67 typename Arg1, typename Arg2>
68struct Replace<TT<T1, T2>, Arg1, Arg2> {
69 typedef TT<typename Replace<T1, Arg1, Arg2>::type,
70 typename Replace<T2, Arg1, Arg2>::type> type;
71};
72
73// Just for kicks...
74template<template<typename, typename> class TT, typename T1,
75 typename Arg1, typename Arg2>
76struct Replace<TT<T1, _2>, Arg1, Arg2> {
77 typedef TT<typename Replace<T1, Arg1, Arg2>::type, Arg2> type;
78};
79
80int array0[is_same<Replace<_1, int, float>::type, int>::value? 1 : -1];
81int array1[is_same<Replace<const _1, int, float>::type, const int>::value? 1 : -1];
82int array2[is_same<Replace<vector<_1>, int, float>::type, vector<int> >::value? 1 : -1];
83int array3[is_same<Replace<vector<const _1>, int, float>::type, vector<const int> >::value? 1 : -1];
84int array4[is_same<Replace<vector<int, _2>, double, float>::type, vector<int, float> >::value? 1 : -1];
Chandler Carruthc712ce12009-12-30 04:10:01 +000085
86// PR5911
87template <typename T, int N> void f(const T (&a)[N]);
88int iarr[] = { 1 };
89void test_PR5911() { f(iarr); }
Chandler Carruthc1263112010-02-07 21:33:28 +000090
91// Must not examine base classes of incomplete type during template argument
92// deduction.
93namespace PR6257 {
94 template <typename T> struct X {
95 template <typename U> X(const X<U>& u);
96 };
97 struct A;
98 void f(A& a);
99 void f(const X<A>& a);
100 void test(A& a) { (void)f(a); }
101}
Douglas Gregor603d81b2010-07-13 08:18:22 +0000102
103// PR7463
104namespace PR7463 {
Chandler Carruthcb3b5a42010-07-14 06:36:18 +0000105 const int f ();
Douglas Gregor603d81b2010-07-13 08:18:22 +0000106 template <typename T_> void g (T_&); // expected-note{{T_ = int}}
107 void h (void) { g(f()); } // expected-error{{no matching function for call}}
108}
John McCall42d7d192010-08-05 09:05:08 +0000109
110namespace test0 {
Davide Italiano32cbff72015-08-15 15:23:14 +0000111 template <class T> void make(const T *(*fn)()); // expected-note {{candidate template ignored: cannot deduce a type for 'T' that would make 'const T' equal 'char'}}
John McCall42d7d192010-08-05 09:05:08 +0000112 char *char_maker();
113 void test() {
114 make(char_maker); // expected-error {{no matching function for call to 'make'}}
115 }
116}
John McCallf7332682010-08-19 00:20:19 +0000117
118namespace test1 {
119 template<typename T> void foo(const T a[3][3]);
120 void test() {
121 int a[3][3];
122 foo(a);
123 }
124}
John McCall08569062010-08-28 22:14:41 +0000125
126// PR7708
127namespace test2 {
128 template<typename T> struct Const { typedef void const type; };
129
130 template<typename T> void f(T, typename Const<T>::type*);
131 template<typename T> void f(T, void const *);
132
133 void test() {
134 void *p = 0;
135 f(0, p);
136 }
137}
John McCall036855a2010-10-12 19:40:14 +0000138
139// rdar://problem/8537391
140namespace test3 {
141 struct Foo {
142 template <void F(char)> static inline void foo();
143 };
144
145 class Bar {
146 template<typename T> static inline void wobble(T ch);
147
148 public:
149 static void madness() {
150 Foo::foo<wobble<char> >();
151 }
152 };
153}
John McCall6730e4d2011-07-15 07:47:58 +0000154
155// Verify that we can deduce enum-typed arguments correctly.
156namespace test14 {
157 enum E { E0, E1 };
158 template <E> struct A {};
159 template <E e> void foo(const A<e> &a) {}
160
161 void test() {
162 A<E0> a;
163 foo(a);
164 }
165}
Richard Smithd8a52a72014-11-12 01:43:45 +0000166
167namespace PR21536 {
168 template<typename ...T> struct X;
169 template<typename A, typename ...B> struct S {
170 static_assert(sizeof...(B) == 1, "");
171 void f() {
172 using T = A;
173 using T = int;
174
175 using U = X<B...>;
176 using U = X<int>;
177 }
178 };
179 template<typename ...T> void f(S<T...>);
180 void g() { f(S<int, int>()); }
181}
Richard Smith96d71c32014-11-12 23:38:38 +0000182
183namespace PR19372 {
184 template <template<typename...> class C, typename ...Us> struct BindBack {
185 template <typename ...Ts> using apply = C<Ts..., Us...>;
186 };
187 template <typename, typename...> struct Y;
188 template <typename ...Ts> using Z = Y<Ts...>;
189
190 using T = BindBack<Z, int>::apply<>;
191 using T = Z<int>;
192
193 using U = BindBack<Z, int, int>::apply<char>;
194 using U = Z<char, int, int>;
Richard Smith316c6dc2014-11-12 23:43:08 +0000195
196 namespace BetterReduction {
197 template<typename ...> struct S;
Richard Smith5357c082014-11-12 23:50:13 +0000198 template<typename ...A> using X = S<A...>; // expected-note {{parameter}}
Richard Smith316c6dc2014-11-12 23:43:08 +0000199 template<typename ...A> using Y = X<A..., A...>;
Richard Smith5357c082014-11-12 23:50:13 +0000200 template<typename ...A> using Z = X<A..., 1, 2, 3>; // expected-error {{must be a type}}
Richard Smith316c6dc2014-11-12 23:43:08 +0000201
202 using T = Y<int>;
203 using T = S<int, int>;
204 }
Richard Smith96d71c32014-11-12 23:38:38 +0000205}
Nathan Sidwell96090022015-01-16 15:20:14 +0000206
207namespace PR18645 {
208 template<typename F> F Quux(F &&f);
209 auto Baz = Quux(Quux<float>);
210}
Richard Smith50d5b972015-12-30 20:56:05 +0000211
212namespace NonDeducedNestedNameSpecifier {
213 template<typename T> struct A {
214 template<typename U> struct B {
215 B(int) {}
216 };
217 };
218
219 template<typename T> int f(A<T>, typename A<T>::template B<T>);
220 int k = f(A<int>(), 0);
221}
Faisal Vali683b0742016-05-19 02:28:21 +0000222
223namespace PR27601_RecursivelyInheritedBaseSpecializationsDeductionAmbiguity {
224namespace ns1 {
225
226template<class...> struct B { };
227template<class H, class ... Ts> struct B<H, Ts...> : B<> { };
228template<class ... Ts> struct D : B<Ts...> { };
229
230template<class T, class ... Ts> void f(B<T, Ts...> &) { }
231
232int main() {
233 D<int, char> d;
234 f<int>(d);
235}
236} //end ns1
237
238namespace ns2 {
239
240template <int i, typename... Es> struct tup_impl;
241
242template <int i> struct tup_impl<i> {}; // empty tail
243
244template <int i, typename Head, typename... Tail>
245struct tup_impl<i, Head, Tail...> : tup_impl<i + 1, Tail...> {
246 using value_type = Head;
247 Head head;
248};
249
250template <typename... Es> struct tup : tup_impl<0, Es...> {};
251
252template <typename Head, int i, typename... Tail>
253Head &get_helper(tup_impl<i, Head, Tail...> &t) {
254 return t.head;
255}
256
257template <typename Head, int i, typename... Tail>
258Head const &get_helper(tup_impl<i, Head, Tail...> const &t) {
259 return t.head;
260}
261
262int main() {
263 tup<int, double, char> t;
264 get_helper<double>(t);
265 return 0;
266}
267} // end ns2
Richard Smith38175a22016-09-28 22:08:38 +0000268}
269
Richard Smith593d6a12016-12-23 01:30:39 +0000270namespace multiple_deduction_different_type {
271 template<typename T, T v> struct X {};
272 template<template<typename T, T> class X, typename T, typename U, int N>
273 void f(X<T, N>, X<U, N>) {} // expected-note 2{{values of conflicting types}}
274 template<template<typename T, T> class X, typename T, typename U, const int *N>
275 void g(X<T, N>, X<U, N>) {} // expected-note 0-2{{values of conflicting types}}
276 int n;
277 void h() {
278 f(X<int, 1+1>(), X<unsigned int, 3-1>()); // expected-error {{no matching function}}
279 f(X<unsigned int, 1+1>(), X<int, 3-1>()); // expected-error {{no matching function}}
280#if __cplusplus > 201402L
281 g(X<const int*, &n>(), X<int*, &n + 1 - 1>()); // expected-error {{no matching function}}
282 g(X<int*, &n>(), X<const int*, &n + 1 - 1>()); // expected-error {{no matching function}}
283#endif
284 }
285
286 template<template<typename T, T> class X, typename T, typename U, T N>
287 void x(X<T, N>, int(*)[N], X<U, N>) {} // expected-note 1+{{candidate}}
288 template<template<typename T, T> class X, typename T, typename U, T N>
289 void x(int(*)[N], X<T, N>, X<U, N>) {} // expected-note 1+{{candidate}}
290 int arr[3];
291 void y() {
292 x(X<int, 3>(), &arr, X<int, 3>());
293 x(&arr, X<int, 3>(), X<int, 3>());
294
295 x(X<int, 3>(), &arr, X<char, 3>()); // expected-error {{no matching function}}
296 x(&arr, X<int, 3>(), X<char, 3>()); // expected-error {{no matching function}}
297
298 x(X<char, 3>(), &arr, X<char, 3>());
299 x(&arr, X<char, 3>(), X<char, 3>());
300 }
301}
302
Richard Smith38175a22016-09-28 22:08:38 +0000303namespace nullptr_deduction {
Richard Smith593d6a12016-12-23 01:30:39 +0000304 using nullptr_t = decltype(nullptr);
305
Richard Smith38175a22016-09-28 22:08:38 +0000306 template<typename T, T v> struct X {};
307 template<typename T, T v> void f(X<T, v>) {
308 static_assert(!v, "");
309 }
Richard Smith593d6a12016-12-23 01:30:39 +0000310 void g() {
311 f(X<int*, nullptr>());
312 f(X<nullptr_t, nullptr>());
313 }
314
315 template<template<typename T, T> class X, typename T, typename U, int *P>
316 void f1(X<T, P>, X<U, P>) {} // expected-note 2{{values of conflicting types}}
317 void h() {
318 f1(X<int*, nullptr>(), X<nullptr_t, nullptr>()); // expected-error {{no matching function}}
319 f1(X<nullptr_t, nullptr>(), X<int*, nullptr>()); // expected-error {{no matching function}}
320 }
321
322 template<template<typename T, T> class X, typename T, typename U, nullptr_t P>
323 void f2(X<T, P>, X<U, P>) {} // expected-note 2{{values of conflicting types}}
324 void i() {
325 f2(X<int*, nullptr>(), X<nullptr_t, nullptr>()); // expected-error {{no matching function}}
326 f2(X<nullptr_t, nullptr>(), X<int*, nullptr>()); // expected-error {{no matching function}}
327 }
328}
329
330namespace member_pointer {
331 struct A { void f(int); };
332 template<typename T, void (A::*F)(T)> struct B;
333 template<typename T> struct C;
334 template<typename T, void (A::*F)(T)> struct C<B<T, F>> {
335 C() { A a; T t; (a.*F)(t); }
336 };
337 C<B<int, &A::f>> c;
Richard Smith38175a22016-09-28 22:08:38 +0000338}
Richard Smith792c22d2016-12-24 04:09:05 +0000339
340namespace deduction_substitution_failure {
Richard Smithe68a38f2016-12-24 04:20:31 +0000341 template<typename T> struct Fail { typedef typename T::error error; }; // expected-error 2{{prior to '::'}}
Richard Smith792c22d2016-12-24 04:09:05 +0000342
343 template<typename T, typename U> struct A {};
344 template<typename T> struct A<T, typename Fail<T>::error> {}; // expected-note {{instantiation of}}
345 A<int, int> ai; // expected-note {{during template argument deduction for class template partial specialization 'A<T, typename Fail<T>::error>' [with T = int]}}
346
Richard Smith792c22d2016-12-24 04:09:05 +0000347 template<typename T, typename U> int B; // expected-warning 0-1 {{extension}}
Richard Smithe68a38f2016-12-24 04:20:31 +0000348 template<typename T> int B<T, typename Fail<T>::error> {}; // expected-note {{instantiation of}}
349 int bi = B<char, char>; // expected-note {{during template argument deduction for variable template partial specialization 'B<T, typename Fail<T>::error>' [with T = char]}}
Richard Smith792c22d2016-12-24 04:09:05 +0000350}
Richard Smithdadcc182017-01-02 23:00:32 +0000351
352namespace deduction_after_explicit_pack {
353 template<typename ...T, typename U> int *f(T ...t, int &r, U *u) { // expected-note {{couldn't infer template argument 'U'}}
354 return u;
355 }
356 template<typename U, typename ...T> int *g(T ...t, int &r, U *u) {
357 return u;
358 }
359 void h(float a, double b, int c) {
360 // FIXME: Under DR1388, this appears to be valid.
361 f<float&, double&>(a, b, c, &c); // expected-error {{no matching}}
362 g<int, float&, double&>(a, b, c, &c); // ok
363 }
364}
Richard Smith539e8e32017-01-04 01:48:55 +0000365
366namespace overload_vs_pack {
367 void f(int);
368 void f(float);
369 void g(double);
370
371 template<typename ...T> struct X {};
372 template<typename ...T> void x(T...);
373
374 template<typename ...T> struct Y { typedef int type(typename T::error...); };
375 template<> struct Y<int, float, double> { typedef int type; };
376
377 template<typename ...T> typename Y<T...>::type g1(X<T...>, void (*...fns)(T)); // expected-note {{deduced conflicting types for parameter 'T' (<int, float> vs. <(no value), double>)}}
378 template<typename ...T> typename Y<T...>::type g2(void(*)(T...), void (*...fns)(T)); // expected-note {{deduced conflicting types for parameter 'T' (<int, float> vs. <(no value), double>)}}
379
380 template<typename T> int &h1(decltype(g1(X<int, float, T>(), f, f, g)) *p);
381 template<typename T> float &h1(...);
382
383 template<typename T> int &h2(decltype(g2(x<int, float, T>, f, f, g)) *p);
384 template<typename T> float &h2(...);
385
386 int n1 = g1(X<int, float>(), f, g); // expected-error {{no matching function}}
387 int n2 = g2(x<int, float>, f, g); // expected-error {{no matching function}}
Richard Smith539e8e32017-01-04 01:48:55 +0000388
389 int &a1 = h1<double>(0); // ok, skip deduction for 'f's, deduce matching value from 'g'
390 int &a2 = h2<double>(0);
391
392 float &b1 = h1<float>(0); // deduce mismatching value from 'g', so we do not trigger instantiation of Y
393 float &b2 = h2<float>(0);
394
395 template<typename ...T> int partial_deduction(void (*...f)(T)); // expected-note {{deduced incomplete pack <(no value), double> for template parameter 'T'}}
396 int pd1 = partial_deduction(f, g); // expected-error {{no matching function}}
397
398 template<typename ...T> int partial_deduction_2(void (*...f)(T), ...); // expected-note {{deduced incomplete pack <(no value), double> for template parameter 'T'}}
399 int pd2 = partial_deduction_2(f, g); // expected-error {{no matching function}}
Richard Smith6298b442017-01-04 02:03:39 +0000400
401 namespace cwg_example {
402 void f(char, char);
403 void f(int, int);
404 void x(int, char);
405
406 template<typename T, typename ...U> void j(void(*)(U...), void (*...fns)(T, U));
407 void test() { j(x, f, x); }
408 }
Richard Smith539e8e32017-01-04 01:48:55 +0000409}