xref: /llvm-project/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp (revision a760df316510fc56576d0934f33577a4ce64b146)
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 }
16 
17 template<typename T> constexpr bool has_type(...) { return false; }
18 template<typename T> constexpr bool has_type(T&) { return true; }
19 
20 std::initializer_list il1 = {1, 2, 3, 4, 5};
21 auto il2 = std::initializer_list{1, 2, 3, 4};
22 auto il3 = std::initializer_list(il1);
23 auto il4 = std::initializer_list{il1, il1, il1};
24 static_assert(has_type<std::initializer_list<int>>(il1));
25 static_assert(has_type<std::initializer_list<int>>(il2));
26 static_assert(has_type<std::initializer_list<int>>(il3));
27 static_assert(has_type<std::initializer_list<std::initializer_list<int>>>(il4));
28 
29 auto il5 = std::initializer_list{il1};
30 // expected-error@-1 {{no viable conversion from 'std::initializer_list<int>' to 'const int'}}
31 
32 template<typename T> struct vector {
33   template<typename Iter> vector(Iter, Iter);
34   vector(std::initializer_list<T>);
35 };
36 
37 template<typename T> vector(std::initializer_list<T>) -> vector<T>;
38 template<typename Iter> explicit vector(Iter, Iter) -> vector<typename Iter::value_type>;
39 template<typename T> explicit vector(std::size_t, T) -> vector<T>;
40 
41 vector v1 = {1, 2, 3, 4};
42 static_assert(has_type<vector<int>>(v1));
43 
44 struct iter { typedef char value_type; } it, end;
45 vector v2(it, end);
46 static_assert(has_type<vector<char>>(v2));
47 
48 vector v3(5, 5);
49 static_assert(has_type<vector<int>>(v3));
50 
51 vector v4 = {it, end};
52 static_assert(has_type<vector<iter>>(v4));
53 
54 vector v5{it, end};
55 static_assert(has_type<vector<iter>>(v5));
56 
57 template<typename ...T> struct tuple { tuple(T...); };
58 template<typename ...T> explicit tuple(T ...t) -> tuple<T...>; // expected-note {{declared}}
59 // FIXME: Remove
60 template<typename ...T> tuple(tuple<T...>) -> tuple<T...>;
61 
62 const int n = 4;
63 tuple ta = tuple{1, 'a', "foo", n};
64 static_assert(has_type<tuple<int, char, const char*, int>>(ta));
65 
66 tuple tb{ta};
67 static_assert(has_type<tuple<int, char, const char*, int>>(tb));
68 
69 // FIXME: This should be tuple<tuple<...>>; when the above guide is removed.
70 tuple tc = {ta};
71 static_assert(has_type<tuple<int, char, const char*, int>>(tc));
72 
73 tuple td = {1, 2, 3}; // expected-error {{selected an explicit deduction guide}}
74 static_assert(has_type<tuple<int, char, const char*, int>>(td));
75 
76 // FIXME: This is a GCC extension for now; if CWG don't allow this, at least
77 // add a warning for it.
78 namespace new_expr {
79   tuple<int> *p = new tuple{0};
80   tuple<float, float> *q = new tuple(1.0f, 2.0f);
81 }
82 
83 namespace ambiguity {
84   template<typename T> struct A {};
85   A(unsigned short) -> A<int>; // expected-note {{candidate}}
86   A(short) -> A<int>; // expected-note {{candidate}}
87   A a = 0; // expected-error {{ambiguous deduction for template arguments of 'A'}}
88 
89   template<typename T> struct B {};
90   template<typename T> B(T(&)(int)) -> B<int>; // expected-note {{candidate function [with T = int]}}
91   template<typename T> B(int(&)(T)) -> B<int>; // expected-note {{candidate function [with T = int]}}
92   int f(int);
93   B b = f; // expected-error {{ambiguous deduction for template arguments of 'B'}}
94 }
95 
96 // FIXME: Revisit this once CWG decides if attributes, and [[deprecated]] in
97 // particular, should be permitted here.
98 namespace deprecated {
99   template<typename T> struct A { A(int); };
100   [[deprecated]] A(int) -> A<void>; // expected-note {{marked deprecated here}}
101   A a = 0; // expected-warning {{'<deduction guide for A>' is deprecated}}
102 }
103 
104 namespace dependent {
105   template<template<typename...> typename A> decltype(auto) a = A{1, 2, 3};
106   static_assert(has_type<vector<int>>(a<vector>));
107   static_assert(has_type<tuple<int, int, int>>(a<tuple>));
108 
109   struct B {
110     template<typename T> struct X { X(T); };
111     X(int) -> X<int>;
112     template<typename T> using Y = X<T>;
113   };
114   template<typename T> void f() {
115     typename T::X tx = 0;
116     typename T::Y ty = 0;
117   }
118   template void f<B>();
119 
120   template<typename T> struct C { C(T); };
121   template<typename T> C(T) -> C<T>;
122   template<typename T> void g(T a) {
123     C b = 0;
124     C c = a;
125     using U = decltype(b); // expected-note {{previous}}
126     using U = decltype(c); // expected-error {{different types ('C<const char *>' vs 'C<int>')}}
127   }
128   void h() {
129     g(0);
130     g("foo"); // expected-note {{instantiation of}}
131   }
132 }
133 
134 namespace look_into_current_instantiation {
135   template<typename U> struct Q {};
136   template<typename T> struct A {
137     using U = T;
138     template<typename> using V = Q<A<T>::U>;
139     template<typename W = int> A(V<W>);
140   };
141   A a = Q<float>(); // ok, can look through class-scope typedefs and alias
142                     // templates, and members of the current instantiation
143   A<float> &r = a;
144 
145   template<typename T> struct B { // expected-note {{could not match 'B<T>' against 'int'}} \
146                                   // expected-note {{implicit deduction guide declared as 'template <typename T> B(B<T>) -> B<T>'}}
147     struct X {
148       typedef T type;
149     };
150     B(typename X::type); // expected-note {{couldn't infer template argument 'T'}} \
151                          // expected-note {{implicit deduction guide declared as 'template <typename T> B(typename X::type) -> B<T>'}}
152   };
153   B b = 0; // expected-error {{no viable}}
154 
155   // We should have a substitution failure in the immediate context of
156   // deduction when using the C(T, U) constructor (probably; core wording
157   // unclear).
158   template<typename T> struct C {
159     using U = typename T::type;
160     C(T, U);
161   };
162 
163   struct R { R(int); typedef R type; };
164   C(...) -> C<R>;
165 
166   C c = {1, 2};
167 }
168 
169 namespace nondeducible {
170   template<typename A, typename B> struct X {};
171 
172   template<typename A> // expected-note {{non-deducible template parameter 'A'}}
173   X() -> X<A, int>; // expected-error {{deduction guide template contains a template parameter that cannot be deduced}}
174 
175   template<typename A> // expected-note {{non-deducible template parameter 'A'}}
176   X(typename X<A, int>::type) -> X<A, int>; // expected-error {{deduction guide template contains a template parameter that cannot be deduced}}
177 
178   template<typename A = int,
179            typename B> // expected-note {{non-deducible template parameter 'B'}}
180   X(int) -> X<A, B>; // expected-error {{deduction guide template contains a template parameter that cannot be deduced}}
181 
182   template<typename A = int,
183            typename ...B>
184   X(float) -> X<A, B...>; // ok
185 
186   template <typename> struct UnnamedTemplateParam {};
187   template <typename>                                  // expected-note {{non-deducible template parameter (anonymous)}}
188   UnnamedTemplateParam() -> UnnamedTemplateParam<int>; // expected-error {{deduction guide template contains a template parameter that cannot be deduced}}
189 }
190 
191 namespace default_args_from_ctor {
192   template <class A> struct S { S(A = 0) {} };
193   S s(0);
194 
195   template <class A> struct T { template<typename B> T(A = 0, B = 0) {} };
196   T t(0, 0);
197 }
198 
199 namespace transform_params {
200   template<typename T, T N, template<T (*v)[N]> typename U, T (*X)[N]>
201   struct A {
202     template<typename V, V M, V (*Y)[M], template<V (*v)[M]> typename W>
203     A(U<X>, W<Y>);
204 
205     static constexpr T v = N;
206   };
207 
208   int n[12];
209   template<int (*)[12]> struct Q {};
210   Q<&n> qn;
211   A a(qn, qn);
212   static_assert(a.v == 12);
213 
214   template<typename ...T> struct B {
215     template<T ...V> B(const T (&...p)[V]) {
216       constexpr int Vs[] = {V...};
217       static_assert(Vs[0] == 3 && Vs[1] == 4 && Vs[2] == 4);
218     }
219     static constexpr int (*p)(T...) = (int(*)(int, char, char))nullptr;
220   };
221   B b({1, 2, 3}, "foo", {'x', 'y', 'z', 'w'}); // ok
222 
223   template<typename ...T> struct C {
224     template<T ...V, template<T...> typename X>
225       C(X<V...>);
226   };
227   template<int...> struct Y {};
228   C c(Y<0, 1, 2>{});
229 
230   template<typename ...T> struct D {
231     template<T ...V> D(Y<V...>);
232   };
233   D d(Y<0, 1, 2>{});
234 }
235 
236 namespace variadic {
237   int arr3[3], arr4[4];
238 
239   // PR32673
240   template<typename T> struct A {
241     template<typename ...U> A(T, U...);
242   };
243   A a(1, 2, 3);
244 
245   template<typename T> struct B {
246     template<int ...N> B(T, int (&...r)[N]);
247   };
248   B b(1, arr3, arr4);
249 
250   template<typename T> struct C {
251     template<template<typename> typename ...U> C(T, U<int>...);
252   };
253   C c(1, a, b);
254 
255   template<typename ...U> struct X {
256     template<typename T> X(T, U...);
257   };
258   X x(1, 2, 3);
259 
260   template<int ...N> struct Y {
261     template<typename T> Y(T, int (&...r)[N]);
262   };
263   Y y(1, arr3, arr4);
264 
265   template<template<typename> typename ...U> struct Z {
266     template<typename T> Z(T, U<int>...);
267   };
268   Z z(1, a, b);
269 }
270 
271 namespace tuple_tests {
272   // The converting n-ary constructor appears viable, deducing T as an empty
273   // pack (until we check its SFINAE constraints).
274   namespace libcxx_1 {
275     template<class ...T> struct tuple {
276       template<class ...Args> struct X { static const bool value = false; };
277       template<class ...U, bool Y = X<U...>::value> tuple(U &&...u);
278     };
279     tuple a = {1, 2, 3};
280   }
281 
282   // Don't get caught by surprise when X<...> doesn't even exist in the
283   // selected specialization!
284   namespace libcxx_2 {
285     template<class ...T> struct tuple {
286       template<class ...Args> struct X { static const bool value = false; };
287       // Substitution into X<U...>::value succeeds but produces the
288       // value-dependent expression
289       //   tuple<T...>::X<>::value
290       // FIXME: Is that the right behavior?
291       template<class ...U, bool Y = X<U...>::value> tuple(U &&...u);
292     };
293     template <> class tuple<> {};
294     tuple a = {1, 2, 3}; // expected-error {{excess elements in struct initializer}}
295   }
296 
297   namespace libcxx_3 {
298     template<typename ...T> struct scoped_lock {
299       scoped_lock(T...);
300     };
301     template<> struct scoped_lock<> {};
302     scoped_lock l = {};
303   }
304 }
305 
306 namespace dependent {
307   template<typename T> struct X { // expected-note 3{{here}}
308     X(T);
309   };
310   template<typename T> int Var(T t) {
311     X x(t);
312     return X(x) + 1; // expected-error {{invalid operands}}
313   }
314   template<typename T> int Cast(T t) {
315     return X(X(t)) + 1; // expected-error {{invalid operands}}
316   }
317   template<typename T> int Cast2(T t) {
318     return (X)(X)t + 1; // expected-error {{deduction not allowed}}
319   }
320   template<typename T> int Cast3(T t) {
321     return X{X{t}} + 1; // expected-error {{invalid operands}}
322   }
323   template<typename T> int Cast4(T t) {
324     return (X){(X){t}} + 1; // expected-error 2{{deduction not allowed}}
325   }
326   template<typename T> int New(T t) {
327     return X(new X(t)) + 1; // expected-error {{invalid operands}}
328   };
329   template<typename T> int *New2(T t) {
330     return new X(X(t)) * 2; // expected-error {{invalid operands}}
331   };
332   template int Var(float); // expected-note {{instantiation of}}
333   template int Cast(float); // expected-note {{instantiation of}}
334   template int Cast3(float); // expected-note {{instantiation of}}
335   template int New(float); // expected-note {{instantiation of}}
336   template int *New2(float); // expected-note {{instantiation of}}
337   template<typename T> int operator+(X<T>, int);
338   template int Var(int);
339   template int Cast(int);
340   template int New(int);
341 
342   template<template<typename> typename Y> void test() {
343     Y(0);
344     new Y(0);
345     Y y(0);
346   }
347   template void test<X>();
348 }
349 
350 namespace injected_class_name {
351   template<typename T = void> struct A {
352     A();
353     template<typename U> A(A<U>);
354   };
355   A<int> a;
356   A b = a;
357   using T = decltype(a);
358   using T = decltype(b);
359 }
360 
361 namespace member_guides {
362   // PR34520
363   template<class>
364   struct Foo {
365     template <class T> struct Bar {
366       Bar(...) {}
367     };
368     Bar(int) -> Bar<int>;
369   };
370   Foo<int>::Bar b = 0;
371 
372   struct A {
373     template<typename T> struct Public; // expected-note {{declared public}}
374     Public(float) -> Public<float>;
375   protected: // expected-note {{declared protected by intervening access specifier}}
376     template<typename T> struct Protected; // expected-note 2{{declared protected}}
377     Protected(float) -> Protected<float>;
378     Public(int) -> Public<int>; // expected-error {{different access}}
379   private: // expected-note {{declared private by intervening access specifier}}
380     template<typename T> struct Private; // expected-note {{declared private}}
381     Protected(int) -> Protected<int>; // expected-error {{different access}}
382   public: // expected-note 2{{declared public by intervening access specifier}}
383     template<typename T> Public(T) -> Public<T>;
384     template<typename T> Protected(T) -> Protected<T>; // expected-error {{different access}}
385     template<typename T> Private(T) -> Private<T>; // expected-error {{different access}}
386   };
387 }
388 
389 namespace rdar41903969 {
390 template <class T> struct A {};
391 template <class T> struct B;
392 template <class T> struct C {
393   C(A<T>&);
394   C(B<T>&);
395 };
396 
397 void foo(A<int> &a, B<int> &b) {
398   (void)C{b};
399   (void)C{a};
400 }
401 
402 template<typename T> struct X {
403   X(std::initializer_list<T>) = delete;
404   X(const X&);
405 };
406 
407 template <class T> struct D : X<T> {};
408 
409 void bar(D<int>& d) {
410   (void)X{d};
411 }
412 }
413 
414 namespace rdar41330135 {
415 template <int> struct A {};
416 template <class T>
417 struct S {
418   template <class U>
419   S(T a, U t, A<sizeof(t)>);
420 };
421 template <class T> struct D {
422   D(T t, A<sizeof(t)>);
423 };
424 int f() {
425   S s(0, 0, A<sizeof(int)>());
426   D d(0, A<sizeof(int)>());
427 }
428 
429 namespace test_dupls {
430 template<unsigned long> struct X {};
431 template<typename T> struct A {
432   A(T t, X<sizeof(t)>);
433 };
434 A a(0, {});
435 template<typename U> struct B {
436   B(U u, X<sizeof(u)>);
437 };
438 B b(0, {});
439 }
440 
441 }
442 
443 namespace no_crash_on_default_arg {
444 class A {
445   template <typename T> class B {
446     B(int c = 1);
447   };
448   // This used to crash due to unparsed default arg above. The diagnostic could
449   // be improved, but the point of this test is to simply check we do not crash.
450   B(); // expected-error {{deduction guide declaration without trailing return type}}
451 };
452 } // namespace no_crash_on_default_arg
453 
454 #pragma clang diagnostic push
455 #pragma clang diagnostic warning "-Wctad-maybe-unsupported"
456 namespace test_implicit_ctad_warning {
457 
458 template <class T>
459 struct Tag {};
460 
461 template <class T>
462 struct NoExplicit { // expected-note {{add a deduction guide to suppress this warning}}
463   NoExplicit(T) {}
464   NoExplicit(T, int) {}
465 };
466 
467 // expected-warning@+1 {{'NoExplicit' may not intend to support class template argument deduction}}
468 NoExplicit ne(42);
469 
470 template <class U>
471 struct HasExplicit {
472   HasExplicit(U) {}
473   HasExplicit(U, int) {}
474 };
475 template <class U> HasExplicit(U, int) -> HasExplicit<Tag<U>>;
476 
477 HasExplicit he(42);
478 
479 // Motivating examples from (taken from Stephan Lavavej's 2018 Cppcon talk)
480 template <class T, class U>
481 struct AmateurPair { // expected-note {{add a deduction guide to suppress this warning}}
482   T first;
483   U second;
484   explicit AmateurPair(const T &t, const U &u) {}
485 };
486 // expected-warning@+1 {{'AmateurPair' may not intend to support class template argument deduction}}
487 AmateurPair p1(42, "hello world"); // deduces to Pair<int, char[12]>
488 
489 template <class T, class U>
490 struct AmateurPair2 { // expected-note {{add a deduction guide to suppress this warning}}
491   T first;
492   U second;
493   explicit AmateurPair2(T t, U u) {}
494 };
495 // expected-warning@+1 {{'AmateurPair2' may not intend to support class template argument deduction}}
496 AmateurPair2 p2(42, "hello world"); // deduces to Pair2<int, const char*>
497 
498 template <class T, class U>
499 struct ProPair {
500   T first; U second;
501     explicit ProPair(T const& t, U  const& u)  {}
502 };
503 template<class T1, class T2>
504 ProPair(T1, T2) -> ProPair<T1, T2>;
505 ProPair p3(42, "hello world"); // deduces to ProPair<int, const char*>
506 static_assert(__is_same(decltype(p3), ProPair<int, const char*>));
507 
508 // Test that user-defined explicit guides suppress the warning even if they
509 // aren't used as candidates.
510 template <class T>
511 struct TestExplicitCtor {
512   TestExplicitCtor(T) {}
513 };
514 template <class T>
515 explicit TestExplicitCtor(TestExplicitCtor<T> const&) -> TestExplicitCtor<void>;
516 TestExplicitCtor<int> ce1{42};
517 TestExplicitCtor ce2 = ce1;
518 static_assert(__is_same(decltype(ce2), TestExplicitCtor<int>), "");
519 
520 struct allow_ctad_t {
521   allow_ctad_t() = delete;
522 };
523 
524 template <class T>
525 struct TestSuppression {
526   TestSuppression(T) {}
527 };
528 TestSuppression(allow_ctad_t)->TestSuppression<void>;
529 TestSuppression ta("abc");
530 static_assert(__is_same(decltype(ta), TestSuppression<const char *>), "");
531 }
532 #pragma clang diagnostic pop
533 
534 namespace PR41549 {
535 
536 template <class H, class P> struct umm;
537 
538 template <class H = int, class P = int>
539 struct umm {
540   umm(H h = 0, P p = 0);
541 };
542 
543 template <class H, class P> struct umm;
544 
545 umm m(1);
546 
547 }
548 
549 namespace PR45124 {
550   class a { int d; };
551   class b : a {};
552 
553   struct x { ~x(); };
554   template<typename> class y { y(x = x()); };
555   template<typename z> y(z)->y<z>;
556 
557   // Not a constant initializer, but trivial default initialization. We won't
558   // detect this as trivial default initialization if synthesizing the implicit
559   // deduction guide 'template<typename T> y(x = x()) -> Y<T>;' leaves behind a
560   // pending cleanup.
561   __thread b g;
562 }
563 
564 namespace PR47175 {
565   template<typename T> struct A { A(T); T x; };
566   template<typename T> int &&n = A(T()).x;
567   int m = n<int>;
568 }
569 
570 // Ensure we don't crash when CTAD fails.
571 template <typename T1, typename T2>
572 struct Foo {   // expected-note {{candidate function template not viable}} \
573                // expected-note {{implicit deduction guide declared as 'template <typename T1, typename T2> Foo(Foo<T1, T2>) -> Foo<T1, T2>'}}
574   Foo(T1, T2); // expected-note {{candidate function template not viable}} \
575                // expected-note {{implicit deduction guide declared as 'template <typename T1, typename T2> Foo(T1, T2) -> Foo<T1, T2>'}}
576 };
577 
578 template <typename... Args>
579 void insert(Args &&...args);
580 
581 void foo() {
582   insert(Foo(2, 2, 2)); // expected-error{{no viable constructor or deduction guide}}
583 }
584 
585 namespace PR52139 {
586   struct Abstract {
587     template <class... Ts>
588     struct overloaded : Ts... {
589       using Ts::operator()...;
590     };
591     template <class... Ts>
592     overloaded(Ts...) -> overloaded<Ts...>;
593 
594   private:
595     virtual void f() = 0;
596   };
597 }
598 
599 namespace function_prototypes {
600   template<class T> using fptr1 = void (*) (T);
601   template<class T> using fptr2 = fptr1<fptr1<T>>;
602 
603   template<class T> void foo0(fptr1<T>) {
604     static_assert(__is_same(T, const char*));
605   }
606   void bar0(const char *const volatile __restrict);
607   void t0() { foo0(&bar0); }
608 
609   template<class T> void foo1(fptr1<const T *>) {
610      static_assert(__is_same(T, char));
611   }
612   void bar1(const char * __restrict);
613   void t1() { foo1(&bar1); }
614 
615   template<class T> void foo2(fptr2<const T *>) {
616     static_assert(__is_same(T, char));
617   }
618   void bar2(fptr1<const char * __restrict>);
619   void t2() { foo2(&bar2); }
620 
621   template<class T> void foo3(fptr1<const T *>) {}
622   void bar3(char * __restrict);
623   void t3() { foo3(&bar3); }
624   // expected-error@-1 {{no matching function for call to 'foo3'}}
625   // expected-note@-4  {{candidate template ignored: cannot deduce a type for 'T' that would make 'const T' equal 'char'}}
626 
627   template<class T> void foo4(fptr2<const T *>) {}
628   void bar4(fptr1<char * __restrict>);
629   void t4() { foo4(&bar4); }
630   // expected-error@-1 {{no matching function for call to 'foo4'}}
631   // expected-note@-4  {{candidate template ignored: cannot deduce a type for 'T' that would make 'const T' equal 'char'}}
632 
633   template<typename T> void foo5(T(T)) {}
634   const int bar5(int);
635   void t5() { foo5(bar5); }
636   // expected-error@-1 {{no matching function for call to 'foo5'}}
637   // expected-note@-4  {{candidate template ignored: deduced conflicting types for parameter 'T' ('const int' vs. 'int')}}
638 
639   struct Foo6 {};
640   template<typename T> void foo6(void(*)(struct Foo6, T)) {}
641   void bar6(Foo6, int);
642   void t6() { foo6(bar6); }
643 }
644 #else
645 
646 // expected-no-diagnostics
647 namespace undefined_warnings {
648   // Make sure we don't get an "undefined but used internal symbol" warning for the deduction guide here.
649   namespace {
650     template <typename T>
651     struct TemplDObj {
652       explicit TemplDObj(T func) noexcept {}
653     };
654     auto test1 = TemplDObj(0);
655 
656     TemplDObj(float) -> TemplDObj<double>;
657     auto test2 = TemplDObj(.0f);
658   }
659 }
660 
661 namespace GH51710 {
662 template<typename T>
663 struct A {
664   A(T f()) {}
665   A(int f(), T) {}
666 
667   A(T array[10]) {}
668   A(int array[10], T) {}
669 };
670 
671 template<typename T>
672 struct B {
673    B(T array[]) {}
674    B(int array[], T) {}
675 };
676 
677 
678 int foo();
679 
680 void bar() {
681   A test1(foo);
682   A test2(foo, 1);
683 
684   int array[10];
685   A test3(array);
686   A test4(array, 1);
687 
688   B test5(array);
689   B test6(array, 1);
690 }
691 } // namespace GH51710
692 
693 #endif
694