blob: c310c651408d6361d8d02e08fe5e5509f91c73c3 [file] [log] [blame]
Richard Smithcb189572017-10-28 01:15:00 +00001// RUN: %clang_cc1 -std=c++1z -verify %s -DERRORS -Wundefined-func-template
2// RUN: %clang_cc1 -std=c++1z -verify %s -UERRORS -Wundefined-func-template
Richard Smith57865822017-08-03 19:24:27 +00003
4// This test is split into two because we only produce "undefined internal"
5// warnings if we didn't produce any errors.
6#if ERRORS
Richard Smith60437622017-02-09 19:17:44 +00007
8namespace std {
9 using size_t = decltype(sizeof(0));
10 template<typename T> struct initializer_list {
11 const T *p;
12 size_t n;
13 initializer_list();
14 };
15 // FIXME: This should probably not be necessary.
16 template<typename T> initializer_list(initializer_list<T>) -> initializer_list<T>;
17}
18
19template<typename T> constexpr bool has_type(...) { return false; }
20template<typename T> constexpr bool has_type(T) { return true; }
21
22std::initializer_list il = {1, 2, 3, 4, 5};
23
24template<typename T> struct vector {
25 template<typename Iter> vector(Iter, Iter);
26 vector(std::initializer_list<T>);
27};
28
29template<typename T> vector(std::initializer_list<T>) -> vector<T>;
30template<typename Iter> explicit vector(Iter, Iter) -> vector<typename Iter::value_type>;
31template<typename T> explicit vector(std::size_t, T) -> vector<T>;
32
33vector v1 = {1, 2, 3, 4};
34static_assert(has_type<vector<int>>(v1));
35
36struct iter { typedef char value_type; } it, end;
37vector v2(it, end);
38static_assert(has_type<vector<char>>(v2));
39
40vector v3(5, 5);
41static_assert(has_type<vector<int>>(v3));
42
Richard Smithafe4aa82017-02-10 02:19:05 +000043vector v4 = {it, end};
44static_assert(has_type<vector<iter>>(v4));
45
46vector v5{it, end};
47static_assert(has_type<vector<iter>>(v5));
Richard Smith60437622017-02-09 19:17:44 +000048
49template<typename ...T> struct tuple { tuple(T...); };
Richard Smithafe4aa82017-02-10 02:19:05 +000050template<typename ...T> explicit tuple(T ...t) -> tuple<T...>; // expected-note {{declared}}
Richard Smith60437622017-02-09 19:17:44 +000051// FIXME: Remove
52template<typename ...T> tuple(tuple<T...>) -> tuple<T...>;
53
54const int n = 4;
55tuple ta = tuple{1, 'a', "foo", n};
56static_assert(has_type<tuple<int, char, const char*, int>>(ta));
57
58tuple tb{ta};
Richard Smithafe4aa82017-02-10 02:19:05 +000059static_assert(has_type<tuple<int, char, const char*, int>>(tb));
Richard Smith60437622017-02-09 19:17:44 +000060
Richard Smithafe4aa82017-02-10 02:19:05 +000061// FIXME: This should be tuple<tuple<...>>; when the above guide is removed.
Richard Smith60437622017-02-09 19:17:44 +000062tuple tc = {ta};
Richard Smithafe4aa82017-02-10 02:19:05 +000063static_assert(has_type<tuple<int, char, const char*, int>>(tc));
Richard Smith60437622017-02-09 19:17:44 +000064
Richard Smithafe4aa82017-02-10 02:19:05 +000065tuple td = {1, 2, 3}; // expected-error {{selected an explicit deduction guide}}
66static_assert(has_type<tuple<int, char, const char*, int>>(td));
Richard Smith60437622017-02-09 19:17:44 +000067
68// FIXME: This is a GCC extension for now; if CWG don't allow this, at least
69// add a warning for it.
70namespace new_expr {
71 tuple<int> *p = new tuple{0};
72 tuple<float, float> *q = new tuple(1.0f, 2.0f);
73}
74
75namespace ambiguity {
76 template<typename T> struct A {};
77 A(unsigned short) -> A<int>; // expected-note {{candidate}}
78 A(short) -> A<int>; // expected-note {{candidate}}
79 A a = 0; // expected-error {{ambiguous deduction for template arguments of 'A'}}
80
81 template<typename T> struct B {};
82 template<typename T> B(T(&)(int)) -> B<int>; // expected-note {{candidate function [with T = int]}}
83 template<typename T> B(int(&)(T)) -> B<int>; // expected-note {{candidate function [with T = int]}}
84 int f(int);
85 B b = f; // expected-error {{ambiguous deduction for template arguments of 'B'}}
86}
87
88// FIXME: Revisit this once CWG decides if attributes, and [[deprecated]] in
89// particular, should be permitted here.
90namespace deprecated {
91 template<typename T> struct A { A(int); };
92 [[deprecated]] A(int) -> A<void>; // expected-note {{marked deprecated here}}
93 A a = 0; // expected-warning {{'<deduction guide for A>' is deprecated}}
94}
Richard Smith541cf972017-02-10 23:10:17 +000095
96namespace dependent {
97 template<template<typename...> typename A> decltype(auto) a = A{1, 2, 3};
98 static_assert(has_type<vector<int>>(a<vector>));
99 static_assert(has_type<tuple<int, int, int>>(a<tuple>));
100
101 struct B {
102 template<typename T> struct X { X(T); };
103 X(int) -> X<int>;
104 template<typename T> using Y = X<T>; // expected-note {{template}}
105 };
106 template<typename T> void f() {
107 typename T::X tx = 0;
108 typename T::Y ty = 0; // expected-error {{alias template 'Y' requires template arguments; argument deduction only allowed for class templates}}
109 }
110 template void f<B>(); // expected-note {{in instantiation of}}
111
112 template<typename T> struct C { C(T); };
113 template<typename T> C(T) -> C<T>;
114 template<typename T> void g(T a) {
115 C b = 0;
116 C c = a;
117 using U = decltype(b); // expected-note {{previous}}
118 using U = decltype(c); // expected-error {{different types ('C<const char *>' vs 'C<int>')}}
119 }
120 void h() {
121 g(0);
122 g("foo"); // expected-note {{instantiation of}}
123 }
124}
Richard Smithcbe07932017-02-14 00:55:25 +0000125
126namespace look_into_current_instantiation {
127 template<typename U> struct Q {};
128 template<typename T> struct A {
129 using U = T;
130 template<typename> using V = Q<A<T>::U>;
131 template<typename W = int> A(V<W>);
132 };
133 A a = Q<float>(); // ok, can look through class-scope typedefs and alias
134 // templates, and members of the current instantiation
135 A<float> &r = a;
136
137 template<typename T> struct B { // expected-note {{could not match 'B<T>' against 'int'}}
138 struct X {
139 typedef T type;
140 };
141 B(typename X::type); // expected-note {{couldn't infer template argument 'T'}}
142 };
143 B b = 0; // expected-error {{no viable}}
Richard Smithc27b3d72017-02-14 01:49:59 +0000144
145 // We should have a substitution failure in the immediate context of
146 // deduction when using the C(T, U) constructor (probably; core wording
147 // unclear).
148 template<typename T> struct C {
149 using U = typename T::type;
150 C(T, U);
151 };
152
153 struct R { R(int); typedef R type; };
154 C(...) -> C<R>;
155
156 C c = {1, 2};
Richard Smithcbe07932017-02-14 00:55:25 +0000157}
Richard Smith4e05eaa2017-02-16 00:36:47 +0000158
159namespace nondeducible {
160 template<typename A, typename B> struct X {};
161
162 template<typename A> // expected-note {{non-deducible template parameter 'A'}}
163 X() -> X<A, int>; // expected-error {{deduction guide template contains a template parameter that cannot be deduced}}
164
165 template<typename A> // expected-note {{non-deducible template parameter 'A'}}
166 X(typename X<A, int>::type) -> X<A, int>; // expected-error {{deduction guide template contains a template parameter that cannot be deduced}}
167
168 template<typename A = int,
169 typename B> // expected-note {{non-deducible template parameter 'B'}}
170 X(int) -> X<A, B>; // expected-error {{deduction guide template contains a template parameter that cannot be deduced}}
171
172 template<typename A = int,
173 typename ...B>
174 X(float) -> X<A, B...>; // ok
175}
Richard Smithefa919a2017-02-16 21:29:21 +0000176
177namespace default_args_from_ctor {
178 template <class A> struct S { S(A = 0) {} };
179 S s(0);
180
181 template <class A> struct T { template<typename B> T(A = 0, B = 0) {} };
182 T t(0, 0);
183}
Richard Smithb4f96252017-02-21 06:30:38 +0000184
185namespace transform_params {
186 template<typename T, T N, template<T (*v)[N]> typename U, T (*X)[N]>
Richard Smith13894182017-04-13 21:37:24 +0000187 struct A {
Richard Smithb4f96252017-02-21 06:30:38 +0000188 template<typename V, V M, V (*Y)[M], template<V (*v)[M]> typename W>
Richard Smith13894182017-04-13 21:37:24 +0000189 A(U<X>, W<Y>);
Richard Smithb4f96252017-02-21 06:30:38 +0000190
191 static constexpr T v = N;
192 };
193
194 int n[12];
195 template<int (*)[12]> struct Q {};
196 Q<&n> qn;
Richard Smith13894182017-04-13 21:37:24 +0000197 A a(qn, qn);
Richard Smithb4f96252017-02-21 06:30:38 +0000198 static_assert(a.v == 12);
199
Richard Smith0cd9c042017-02-21 08:42:39 +0000200 template<typename ...T> struct B {
201 template<T ...V> B(const T (&...p)[V]) {
202 constexpr int Vs[] = {V...};
203 static_assert(Vs[0] == 3 && Vs[1] == 4 && Vs[2] == 4);
204 }
205 static constexpr int (*p)(T...) = (int(*)(int, char, char))nullptr;
Richard Smithb4f96252017-02-21 06:30:38 +0000206 };
Richard Smith0cd9c042017-02-21 08:42:39 +0000207 B b({1, 2, 3}, "foo", {'x', 'y', 'z', 'w'}); // ok
208
Richard Smith13894182017-04-13 21:37:24 +0000209 template<typename ...T> struct C {
Richard Smith0cd9c042017-02-21 08:42:39 +0000210 template<T ...V, template<T...> typename X>
Richard Smith13894182017-04-13 21:37:24 +0000211 C(X<V...>);
Richard Smith0cd9c042017-02-21 08:42:39 +0000212 };
213 template<int...> struct Y {};
Richard Smith13894182017-04-13 21:37:24 +0000214 C c(Y<0, 1, 2>{});
Richard Smith130cc442017-02-21 23:49:18 +0000215
216 template<typename ...T> struct D {
217 template<T ...V> D(Y<V...>);
218 };
219 D d(Y<0, 1, 2>{});
Richard Smithb4f96252017-02-21 06:30:38 +0000220}
Richard Smith479ba8e2017-04-20 01:15:31 +0000221
222namespace variadic {
223 int arr3[3], arr4[4];
224
225 // PR32673
226 template<typename T> struct A {
227 template<typename ...U> A(T, U...);
228 };
229 A a(1, 2, 3);
230
231 template<typename T> struct B {
232 template<int ...N> B(T, int (&...r)[N]);
233 };
234 B b(1, arr3, arr4);
235
236 template<typename T> struct C {
237 template<template<typename> typename ...U> C(T, U<int>...);
238 };
239 C c(1, a, b);
240
241 template<typename ...U> struct X {
242 template<typename T> X(T, U...);
243 };
244 X x(1, 2, 3);
245
246 template<int ...N> struct Y {
247 template<typename T> Y(T, int (&...r)[N]);
248 };
249 Y y(1, arr3, arr4);
250
251 template<template<typename> typename ...U> struct Z {
252 template<typename T> Z(T, U<int>...);
253 };
254 Z z(1, a, b);
255}
Richard Smithe6d4b772017-06-07 02:42:27 +0000256
257namespace tuple_tests {
258 // The converting n-ary constructor appears viable, deducing T as an empty
259 // pack (until we check its SFINAE constraints).
260 namespace libcxx_1 {
261 template<class ...T> struct tuple {
262 template<class ...Args> struct X { static const bool value = false; };
263 template<class ...U, bool Y = X<U...>::value> tuple(U &&...u);
264 };
265 tuple a = {1, 2, 3};
266 }
267
268 // Don't get caught by surprise when X<...> doesn't even exist in the
269 // selected specialization!
270 namespace libcxx_2 {
271 template<class ...T> struct tuple { // expected-note {{candidate}}
272 template<class ...Args> struct X { static const bool value = false; };
273 template<class ...U, bool Y = X<U...>::value> tuple(U &&...u);
274 // expected-note@-1 {{substitution failure [with T = <>, U = <int, int, int>]: cannot reference member of primary template because deduced class template specialization 'tuple<>' is an explicit specialization}}
275 };
276 template <> class tuple<> {};
277 tuple a = {1, 2, 3}; // expected-error {{no viable constructor or deduction guide}}
278 }
Richard Smith4f440e32017-06-08 01:08:50 +0000279
280 namespace libcxx_3 {
281 template<typename ...T> struct scoped_lock {
282 scoped_lock(T...);
283 };
284 template<> struct scoped_lock<> {};
285 scoped_lock l = {};
286 }
Richard Smithe6d4b772017-06-07 02:42:27 +0000287}
Richard Smith57865822017-08-03 19:24:27 +0000288
Richard Smith08877542017-08-11 02:04:19 +0000289namespace dependent {
290 template<typename T> struct X {
291 X(T);
292 };
293 template<typename T> int Var(T t) {
294 X x(t);
295 return X(x) + 1; // expected-error {{invalid operands}}
296 }
297 template<typename T> int Cast(T t) {
298 return X(X(t)) + 1; // expected-error {{invalid operands}}
299 }
300 template<typename T> int New(T t) {
301 return X(new X(t)) + 1; // expected-error {{invalid operands}}
302 };
303 template int Var(float); // expected-note {{instantiation of}}
304 template int Cast(float); // expected-note {{instantiation of}}
305 template int New(float); // expected-note {{instantiation of}}
306 template<typename T> int operator+(X<T>, int);
307 template int Var(int);
308 template int Cast(int);
309 template int New(int);
Richard Smithcff42012018-09-28 03:18:53 +0000310
311 template<template<typename> typename Y> void test() {
312 Y(0);
313 new Y(0);
314 Y y(0);
315 }
316 template void test<X>();
Richard Smith08877542017-08-11 02:04:19 +0000317}
318
Richard Smith13373182018-01-04 01:24:17 +0000319namespace injected_class_name {
320 template<typename T = void> struct A {
321 A();
322 template<typename U> A(A<U>);
323 };
324 A<int> a;
325 A b = a;
326 using T = decltype(a);
327 using T = decltype(b);
328}
329
Richard Smith2600c632018-05-30 20:24:10 +0000330namespace member_guides {
331 // PR34520
332 template<class>
333 struct Foo {
334 template <class T> struct Bar {
335 Bar(...) {}
336 };
337 Bar(int) -> Bar<int>;
338 };
339 Foo<int>::Bar b = 0;
Richard Smithe4899c12018-05-30 22:13:43 +0000340
341 struct A {
342 template<typename T> struct Public; // expected-note {{declared public}}
343 Public(float) -> Public<float>;
344 protected: // expected-note {{declared protected by intervening access specifier}}
345 template<typename T> struct Protected; // expected-note 2{{declared protected}}
346 Protected(float) -> Protected<float>;
347 Public(int) -> Public<int>; // expected-error {{different access}}
348 private: // expected-note {{declared private by intervening access specifier}}
349 template<typename T> struct Private; // expected-note {{declared private}}
350 Protected(int) -> Protected<int>; // expected-error {{different access}}
351 public: // expected-note 2{{declared public by intervening access specifier}}
352 template<typename T> Public(T) -> Public<T>;
353 template<typename T> Protected(T) -> Protected<T>; // expected-error {{different access}}
354 template<typename T> Private(T) -> Private<T>; // expected-error {{different access}}
355 };
Richard Smith2600c632018-05-30 20:24:10 +0000356}
357
Erik Pilkingtondd0b3442018-07-26 23:40:42 +0000358namespace rdar41903969 {
359template <class T> struct A {};
360template <class T> struct B;
361template <class T> struct C {
362 C(A<T>&);
363 C(B<T>&);
364};
365
366void foo(A<int> &a, B<int> &b) {
367 (void)C{b};
368 (void)C{a};
369}
370
371template<typename T> struct X {
372 X(std::initializer_list<T>) = delete;
373 X(const X&);
374};
375
376template <class T> struct D : X<T> {};
377
378void bar(D<int>& d) {
379 (void)X{d};
380}
381}
382
Erik Pilkington69770d32018-07-27 21:23:48 +0000383namespace rdar41330135 {
384template <int> struct A {};
385template <class T>
386struct S {
387 template <class U>
388 S(T a, U t, A<sizeof(t)>);
389};
390template <class T> struct D {
391 D(T t, A<sizeof(t)>);
392};
393int f() {
394 S s(0, 0, A<sizeof(int)>());
395 D d(0, A<sizeof(int)>());
396}
397
398namespace test_dupls {
399template<unsigned long> struct X {};
400template<typename T> struct A {
401 A(T t, X<sizeof(t)>);
402};
403A a(0, {});
404template<typename U> struct B {
405 B(U u, X<sizeof(u)>);
406};
407B b(0, {});
408}
409
410}
411
Richard Smith57865822017-08-03 19:24:27 +0000412#else
413
414// expected-no-diagnostics
415namespace undefined_warnings {
416 // Make sure we don't get an "undefined but used internal symbol" warning for the deduction guide here.
417 namespace {
418 template <typename T>
419 struct TemplDObj {
420 explicit TemplDObj(T func) noexcept {}
421 };
422 auto test1 = TemplDObj(0);
423
424 TemplDObj(float) -> TemplDObj<double>;
425 auto test2 = TemplDObj(.0f);
426 }
427}
428#endif