xref: /llvm-project/clang/test/SemaTemplate/ctad.cpp (revision 3b639d7d1d9b9f352c57460deaf70aaad238f8d9)
1 // RUN: %clang_cc1 -std=c++17 -verify %s
2 
3 namespace pr41427 {
4   template <typename T> class A {
5   public:
A(void (*)(T))6     A(void (*)(T)) {}
7   };
8 
D(int)9   void D(int) {}
10 
f()11   void f() {
12     A a(&D);
13     using T = decltype(a);
14     using T = A<int>;
15   }
16 }
17 
18 namespace Access {
19   struct B {
20   protected:
21     struct type {};
22   };
23   template<typename T> struct D : B { // expected-note {{not viable}} \
24                                          expected-note {{implicit deduction guide declared as 'template <typename T> D(D<T>) -> D<T>'}}
25     D(T, typename T::type); // expected-note {{private member}} \
26                             // expected-note {{implicit deduction guide declared as 'template <typename T> D(T, typename T::type) -> D<T>'}}
27   };
28   D b = {B(), {}};
29 
30   class X {
31     using type = int;
32   };
33   D x = {X(), {}}; // expected-error {{no viable constructor or deduction guide}}
34 
35   // Once we implement proper support for dependent nested name specifiers in
36   // friends, this should still work.
37   class Y {
38     template <typename T> friend D<T>::D(T, typename T::type); // expected-warning {{dependent nested name specifier}}
39     struct type {};
40   };
41   D y = {Y(), {}};
42 
43   class Z {
44     template <typename T> friend class D;
45     struct type {};
46   };
47   D z = {Z(), {}};
48 }
49 
50 namespace GH69987 {
51 template<class> struct X {};
52 template<class = void> struct X;
53 X x;
54 
55 template<class T, class B> struct Y { Y(T); };
56 template<class T, class B=void> struct Y ;
57 Y y(1);
58 }
59 
60 namespace NoCrashOnGettingDefaultArgLoc {
61 template <typename>
62 class A {
63   A(int = 1); // expected-note {{candidate template ignored: couldn't infer template argumen}} \
64               // expected-note {{implicit deduction guide declared as 'template <typename> D(int = <null expr>) -> D<type-parameter-0-0>'}}
65 };
66 class C : A<int> {
67   using A::A;
68 };
69 template <typename>
70 class D : C { // expected-note {{candidate function template not viable: requires 1 argument}} \
71                  expected-note {{implicit deduction guide declared as 'template <typename> D(D<type-parameter-0-0>) -> D<type-parameter-0-0>'}}
72   using C::C;
73 };
74 D abc; // expected-error {{no viable constructor or deduction guide}}
75 }
76