1 | // 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 |
3 | |
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 |
7 | |
8 | namespace 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 | |
19 | template<typename T> constexpr bool has_type(...) { return false; } |
20 | template<typename T> constexpr bool has_type(T) { return true; } |
21 | |
22 | std::initializer_list il = {1, 2, 3, 4, 5}; |
23 | |
24 | template<typename T> struct vector { |
25 | template<typename Iter> vector(Iter, Iter); |
26 | vector(std::initializer_list<T>); |
27 | }; |
28 | |
29 | template<typename T> vector(std::initializer_list<T>) -> vector<T>; |
30 | template<typename Iter> explicit vector(Iter, Iter) -> vector<typename Iter::value_type>; |
31 | template<typename T> explicit vector(std::size_t, T) -> vector<T>; |
32 | |
33 | vector v1 = {1, 2, 3, 4}; |
34 | static_assert(has_type<vector<int>>(v1)); |
35 | |
36 | struct iter { typedef char value_type; } it, end; |
37 | vector v2(it, end); |
38 | static_assert(has_type<vector<char>>(v2)); |
39 | |
40 | vector v3(5, 5); |
41 | static_assert(has_type<vector<int>>(v3)); |
42 | |
43 | vector v4 = {it, end}; |
44 | static_assert(has_type<vector<iter>>(v4)); |
45 | |
46 | vector v5{it, end}; |
47 | static_assert(has_type<vector<iter>>(v5)); |
48 | |
49 | template<typename ...T> struct tuple { tuple(T...); }; |
50 | template<typename ...T> explicit tuple(T ...t) -> tuple<T...>; // expected-note {{declared}} |
51 | // FIXME: Remove |
52 | template<typename ...T> tuple(tuple<T...>) -> tuple<T...>; |
53 | |
54 | const int n = 4; |
55 | tuple ta = tuple{1, 'a', "foo", n}; |
56 | static_assert(has_type<tuple<int, char, const char*, int>>(ta)); |
57 | |
58 | tuple tb{ta}; |
59 | static_assert(has_type<tuple<int, char, const char*, int>>(tb)); |
60 | |
61 | // FIXME: This should be tuple<tuple<...>>; when the above guide is removed. |
62 | tuple tc = {ta}; |
63 | static_assert(has_type<tuple<int, char, const char*, int>>(tc)); |
64 | |
65 | tuple td = {1, 2, 3}; // expected-error {{selected an explicit deduction guide}} |
66 | static_assert(has_type<tuple<int, char, const char*, int>>(td)); |
67 | |
68 | // FIXME: This is a GCC extension for now; if CWG don't allow this, at least |
69 | // add a warning for it. |
70 | namespace new_expr { |
71 | tuple<int> *p = new tuple{0}; |
72 | tuple<float, float> *q = new tuple(1.0f, 2.0f); |
73 | } |
74 | |
75 | namespace 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. |
90 | namespace 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 | } |
95 | |
96 | namespace 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 | } |
125 | |
126 | namespace 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}} |
144 | |
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}; |
157 | } |
158 | |
159 | namespace 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 | } |
176 | |
177 | namespace 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 | } |
184 | |
185 | namespace transform_params { |
186 | template<typename T, T N, template<T (*v)[N]> typename U, T (*X)[N]> |
187 | struct A { |
188 | template<typename V, V M, V (*Y)[M], template<V (*v)[M]> typename W> |
189 | A(U<X>, W<Y>); |
190 | |
191 | static constexpr T v = N; |
192 | }; |
193 | |
194 | int n[12]; |
195 | template<int (*)[12]> struct Q {}; |
196 | Q<&n> qn; |
197 | A a(qn, qn); |
198 | static_assert(a.v == 12); |
199 | |
200 | 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; |
206 | }; |
207 | B b({1, 2, 3}, "foo", {'x', 'y', 'z', 'w'}); // ok |
208 | |
209 | template<typename ...T> struct C { |
210 | template<T ...V, template<T...> typename X> |
211 | C(X<V...>); |
212 | }; |
213 | template<int...> struct Y {}; |
214 | C c(Y<0, 1, 2>{}); |
215 | |
216 | template<typename ...T> struct D { |
217 | template<T ...V> D(Y<V...>); |
218 | }; |
219 | D d(Y<0, 1, 2>{}); |
220 | } |
221 | |
222 | namespace 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 | } |
256 | |
257 | namespace 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 | } |
279 | |
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 | } |
287 | } |
288 | |
289 | namespace 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); |
310 | |
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>(); |
317 | } |
318 | |
319 | namespace 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 | |
330 | namespace 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; |
340 | |
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 | }; |
356 | } |
357 | |
358 | namespace rdar41903969 { |
359 | template <class T> struct A {}; |
360 | template <class T> struct B; |
361 | template <class T> struct C { |
362 | C(A<T>&); |
363 | C(B<T>&); |
364 | }; |
365 | |
366 | void foo(A<int> &a, B<int> &b) { |
367 | (void)C{b}; |
368 | (void)C{a}; |
369 | } |
370 | |
371 | template<typename T> struct X { |
372 | X(std::initializer_list<T>) = delete; |
373 | X(const X&); |
374 | }; |
375 | |
376 | template <class T> struct D : X<T> {}; |
377 | |
378 | void bar(D<int>& d) { |
379 | (void)X{d}; |
380 | } |
381 | } |
382 | |
383 | namespace rdar41330135 { |
384 | template <int> struct A {}; |
385 | template <class T> |
386 | struct S { |
387 | template <class U> |
388 | S(T a, U t, A<sizeof(t)>); |
389 | }; |
390 | template <class T> struct D { |
391 | D(T t, A<sizeof(t)>); |
392 | }; |
393 | int f() { |
394 | S s(0, 0, A<sizeof(int)>()); |
395 | D d(0, A<sizeof(int)>()); |
396 | } |
397 | |
398 | namespace test_dupls { |
399 | template<unsigned long> struct X {}; |
400 | template<typename T> struct A { |
401 | A(T t, X<sizeof(t)>); |
402 | }; |
403 | A a(0, {}); |
404 | template<typename U> struct B { |
405 | B(U u, X<sizeof(u)>); |
406 | }; |
407 | B b(0, {}); |
408 | } |
409 | |
410 | } |
411 | |
412 | #pragma clang diagnostic push |
413 | #pragma clang diagnostic warning "-Wctad-maybe-unsupported" |
414 | namespace test_implicit_ctad_warning { |
415 | |
416 | template <class T> |
417 | struct Tag {}; |
418 | |
419 | template <class T> |
420 | struct NoExplicit { // expected-note {{add a deduction guide to suppress this warning}} |
421 | NoExplicit(T) {} |
422 | NoExplicit(T, int) {} |
423 | }; |
424 | |
425 | // expected-warning@+1 {{'NoExplicit' may not intend to support class template argument deduction}} |
426 | NoExplicit ne(42); |
427 | |
428 | template <class U> |
429 | struct HasExplicit { |
430 | HasExplicit(U) {} |
431 | HasExplicit(U, int) {} |
432 | }; |
433 | template <class U> HasExplicit(U, int) -> HasExplicit<Tag<U>>; |
434 | |
435 | HasExplicit he(42); |
436 | |
437 | // Motivating examples from (taken from Stephan Lavavej's 2018 Cppcon talk) |
438 | template <class T, class U> |
439 | struct AmateurPair { // expected-note {{add a deduction guide to suppress this warning}} |
440 | T first; |
441 | U second; |
442 | explicit AmateurPair(const T &t, const U &u) {} |
443 | }; |
444 | // expected-warning@+1 {{'AmateurPair' may not intend to support class template argument deduction}} |
445 | AmateurPair p1(42, "hello world"); // deduces to Pair<int, char[12]> |
446 | |
447 | template <class T, class U> |
448 | struct AmateurPair2 { // expected-note {{add a deduction guide to suppress this warning}} |
449 | T first; |
450 | U second; |
451 | explicit AmateurPair2(T t, U u) {} |
452 | }; |
453 | // expected-warning@+1 {{'AmateurPair2' may not intend to support class template argument deduction}} |
454 | AmateurPair2 p2(42, "hello world"); // deduces to Pair2<int, const char*> |
455 | |
456 | template <class T, class U> |
457 | struct ProPair { |
458 | T first; U second; |
459 | explicit ProPair(T const& t, U const& u) {} |
460 | }; |
461 | template<class T1, class T2> |
462 | ProPair(T1, T2) -> ProPair<T1, T2>; |
463 | ProPair p3(42, "hello world"); // deduces to ProPair<int, const char*> |
464 | static_assert(__is_same(decltype(p3), ProPair<int, const char*>)); |
465 | |
466 | // Test that user-defined explicit guides suppress the warning even if they |
467 | // aren't used as candidates. |
468 | template <class T> |
469 | struct TestExplicitCtor { |
470 | TestExplicitCtor(T) {} |
471 | }; |
472 | template <class T> |
473 | explicit TestExplicitCtor(TestExplicitCtor<T> const&) -> TestExplicitCtor<void>; |
474 | TestExplicitCtor<int> ce1{42}; |
475 | TestExplicitCtor ce2 = ce1; |
476 | static_assert(__is_same(decltype(ce2), TestExplicitCtor<int>), ""); |
477 | |
478 | struct allow_ctad_t { |
479 | allow_ctad_t() = delete; |
480 | }; |
481 | |
482 | template <class T> |
483 | struct TestSuppression { |
484 | TestSuppression(T) {} |
485 | }; |
486 | TestSuppression(allow_ctad_t)->TestSuppression<void>; |
487 | TestSuppression ta("abc"); |
488 | static_assert(__is_same(decltype(ta), TestSuppression<const char *>), ""); |
489 | } |
490 | #pragma clang diagnostic pop |
491 | |
492 | #else |
493 | |
494 | // expected-no-diagnostics |
495 | namespace undefined_warnings { |
496 | // Make sure we don't get an "undefined but used internal symbol" warning for the deduction guide here. |
497 | namespace { |
498 | template <typename T> |
499 | struct TemplDObj { |
500 | explicit TemplDObj(T func) noexcept {} |
501 | }; |
502 | auto test1 = TemplDObj(0); |
503 | |
504 | TemplDObj(float) -> TemplDObj<double>; |
505 | auto test2 = TemplDObj(.0f); |
506 | } |
507 | } |
508 | #endif |
509 | |