xref: /llvm-project/clang/test/Parser/cxx1z-class-template-argument-deduction.cpp (revision ee57984c111bccc8fd809b2a9f43a4db21b6d66e)
1 // RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -verify %s
2 
3 template<typename T> struct A {}; // expected-note 35{{declared here}}
4 
5 // Make sure we still correctly parse cases where a template can appear without arguments.
6 namespace template_template_arg {
7   template<template<typename> typename> struct X {};
8   template<typename> struct Y {};
9 
10   X<A> xa;
11   Y<A> ya; // expected-error {{requires template arguments}}
12   X<::A> xcca;
13   Y<::A> ycca; // expected-error {{requires template arguments}}
14 
15   template<template<typename> typename = A> struct XD {};
16   template<typename = A> struct YD {}; // expected-error {{requires template arguments}}
17   template<template<typename> typename = ::A> struct XCCD {};
18   template<typename = ::A> struct YCCD {}; // expected-error {{requires template arguments}}
19 
20   // FIXME: replacing the invalid type with 'int' here is horrible
21   template <A a = A<int>()> class C { }; // expected-error {{requires template arguments}} expected-error {{not implicitly convertible to 'int'}}
22   template<typename T = A> struct G { }; // expected-error {{requires template arguments}}
23 }
24 
25 namespace injected_class_name {
26   template<typename T> struct A {
27     A(T);
28     void f(int) {
29       A a = 1;
30       injected_class_name::A b = 1; // expected-error {{not yet supported}}
31     }
32     void f(T);
33   };
34   A<short> ai = 1;
35   A<double>::A b(1); // expected-error {{constructor name}}
36 }
37 
38 struct member {
39   A a; // expected-error {{requires template arguments}}
40   A *b; // expected-error {{requires template arguments}}
41   const A c; // expected-error {{requires template arguments}}
42 
43   void f() throw (A); // expected-error {{requires template arguments}}
44 
45   friend A; // expected-error {{requires template arguments; argument deduction not allowed in friend declaration}}
46 
47   operator A(); // expected-error {{requires template arguments; argument deduction not allowed in conversion function type}}
48 
49   static A x; // expected-error {{requires an initializer}}
50   static A y = 0; // expected-error {{not yet supported}}
51 };
52 
53 namespace in_typedef {
54   typedef A *AutoPtr; // expected-error {{requires template arguments; argument deduction not allowed in typedef}}
55   typedef A (*PFun)(int a); // expected-error{{requires template arguments; argument deduction not allowed in typedef}}
56   typedef A Fun(int a) -> decltype(a + a); // expected-error{{requires template arguments; argument deduction not allowed in function return type}}
57 }
58 
59 namespace stmt {
60   void g(A a) { // expected-error{{requires template arguments; argument deduction not allowed in function prototype}}
61     try { }
62     catch (A &a) { } // expected-error{{requires template arguments; argument deduction not allowed in exception declaration}}
63     catch (const A a) { } // expected-error{{requires template arguments; argument deduction not allowed in exception declaration}}
64     try { } catch (A a) { } // expected-error{{requires template arguments; argument deduction not allowed in exception declaration}}
65 
66     // FIXME: The standard only permits class template argument deduction in a
67     // simple-declaration or cast. We also permit it in conditions,
68     // for-range-declarations, member-declarations for static data members, and
69     // new-expressions, because not doing so would be bizarre.
70     A local = 0; // expected-error {{not yet supported}}
71     static A local_static = 0; // expected-error {{not yet supported}}
72     static thread_local A thread_local_static = 0; // expected-error {{not yet supported}}
73     if (A a = 0) {} // expected-error {{not yet supported}}
74     if (A a = 0; a) {} // expected-error {{not yet supported}}
75     switch (A a = 0) {} // expected-error {{not yet supported}}
76     switch (A a = 0; a) {} // expected-error {{not yet supported}}
77     for (A a = 0; a; /**/) {} // expected-error {{not yet supported}}
78     for (/**/; A a = 0; /**/) {} // expected-error {{not yet supported}}
79     while (A a = 0) {} // expected-error {{not yet supported}}
80     int arr[3];
81     for (A a : arr) {} // expected-error {{not yet supported}}
82   }
83 
84   namespace std {
85     class type_info;
86   }
87 }
88 
89 namespace expr {
90   template<typename T> struct U {};
91   void j() {
92     (void)typeid(A); // expected-error{{requires template arguments; argument deduction not allowed here}}
93     (void)sizeof(A); // expected-error{{requires template arguments; argument deduction not allowed here}}
94     (void)__alignof(A); // expected-error{{requires template arguments; argument deduction not allowed here}}
95 
96     U<A> v; // expected-error {{requires template arguments}}
97 
98     int n;
99     (void)dynamic_cast<A&>(n); // expected-error{{requires template arguments; argument deduction not allowed here}}
100     (void)static_cast<A*>(&n); // expected-error{{requires template arguments; argument deduction not allowed here}}
101     (void)reinterpret_cast<A*>(&n); // expected-error{{requires template arguments; argument deduction not allowed here}}
102     (void)const_cast<A>(n); // expected-error{{requires template arguments; argument deduction not allowed here}}
103     (void)*(A*)(&n); // expected-error{{requires template arguments; argument deduction not allowed here}}
104     (void)(A)(n); // expected-error{{requires template arguments; argument deduction not allowed here}}
105     (void)(A){n}; // expected-error{{requires template arguments; argument deduction not allowed here}}
106 
107     (void)A(n); // expected-error {{not yet supported}}
108     (void)A{n}; // expected-error {{not yet supported}}
109     (void)new A(n); // expected-error {{not yet supported}}
110     (void)new A{n}; // expected-error {{not yet supported}}
111     // FIXME: We should diagnose the lack of an initializer here.
112     (void)new A; // expected-error {{not yet supported}}
113   }
114 }
115 
116 namespace decl {
117   enum E : A {}; // expected-error{{requires template arguments; argument deduction not allowed here}}
118   struct F : A {}; // expected-error{{expected class name}}
119 
120   using B = A; // expected-error{{requires template arguments}}
121 
122   auto k() -> A; // expected-error{{requires template arguments}}
123 
124   A a; // expected-error {{requires an initializer}}
125   A b = 0; // expected-error {{not yet supported}}
126   const A c = 0; // expected-error {{not yet supported}}
127   A (parens) = 0; // expected-error {{cannot use parentheses when declaring variable with deduced class template specialization type}}
128   A *p = 0; // expected-error {{cannot form pointer to deduced class template specialization type}}
129   A &r = *p; // expected-error {{cannot form reference to deduced class template specialization type}}
130   A arr[3] = 0; // expected-error {{cannot form array of deduced class template specialization type}}
131   A F::*pm = 0; // expected-error {{cannot form pointer to deduced class template specialization type}}
132   A (*fp)() = 0; // expected-error {{cannot form function returning deduced class template specialization type}}
133   A [x, y] = 0; // expected-error {{cannot be declared with type 'A'}} expected-error {{not yet supported}}
134 }
135 
136 namespace typename_specifier {
137   struct F {};
138 
139   void e() {
140     (void) typename ::A(0); // expected-error {{not yet supported}}
141     (void) typename ::A{0}; // expected-error {{not yet supported}}
142     new typename ::A(0); // expected-error {{not yet supported}}
143     new typename ::A{0}; // expected-error {{not yet supported}}
144     typename ::A a = 0; // expected-error {{not yet supported}}
145     const typename ::A b = 0; // expected-error {{not yet supported}}
146     if (typename ::A a = 0) {} // expected-error {{not yet supported}}
147     for (typename ::A a = 0; typename ::A b = 0; /**/) {} // expected-error 2{{not yet supported}}
148 
149     (void)(typename ::A)(0); // expected-error{{requires template arguments; argument deduction not allowed here}}
150     (void)(typename ::A){0}; // expected-error{{requires template arguments; argument deduction not allowed here}}
151   }
152   typename ::A a = 0; // expected-error {{not yet supported}}
153   const typename ::A b = 0; // expected-error {{not yet supported}}
154   typename ::A (parens) = 0; // expected-error {{cannot use parentheses when declaring variable with deduced class template specialization type}}
155   typename ::A *p = 0; // expected-error {{cannot form pointer to deduced class template specialization type}}
156   typename ::A &r = *p; // expected-error {{cannot form reference to deduced class template specialization type}}
157   typename ::A arr[3] = 0; // expected-error {{cannot form array of deduced class template specialization type}}
158   typename ::A F::*pm = 0; // expected-error {{cannot form pointer to deduced class template specialization type}}
159   typename ::A (*fp)() = 0; // expected-error {{cannot form function returning deduced class template specialization type}}
160   typename ::A [x, y] = 0; // expected-error {{cannot be declared with type 'typename ::A'}} expected-error {{not yet supported}}
161 
162   struct X { template<typename T> struct A {}; }; // expected-note 8{{template}}
163 
164   template<typename T> void f() {
165     (void) typename T::A(0); // expected-error {{not yet supported}}
166     (void) typename T::A{0}; // expected-error {{not yet supported}}
167     new typename T::A(0); // expected-error {{not yet supported}}
168     new typename T::A{0}; // expected-error {{not yet supported}}
169     typename T::A a = 0; // expected-error {{not yet supported}}
170     const typename T::A b = 0; // expected-error {{not yet supported}}
171     if (typename T::A a = 0) {} // expected-error {{not yet supported}}
172     for (typename T::A a = 0; typename T::A b = 0; /**/) {} // expected-error 2{{not yet supported}}
173 
174     {(void)(typename T::A)(0);} // expected-error{{refers to class template member}}
175     {(void)(typename T::A){0};} // expected-error{{refers to class template member}}
176     {typename T::A (parens) = 0;} // expected-error {{refers to class template member in 'typename_specifier::X'; argument deduction not allowed here}}
177     {typename T::A *p = 0;} // expected-error {{refers to class template member}}
178     {typename T::A &r = *p;} // expected-error {{refers to class template member}}
179     {typename T::A arr[3] = 0;} // expected-error {{refers to class template member}}
180     {typename T::A F::*pm = 0;} // expected-error {{refers to class template member}}
181     {typename T::A (*fp)() = 0;} // expected-error {{refers to class template member}}
182     {typename T::A [x, y] = 0;} // expected-error {{cannot be declared with type 'typename T::A'}} expected-error {{not yet supported}}
183   }
184   template void f<X>(); // expected-note {{instantiation of}}
185 
186   template<typename T> void g(typename T::A = 0); // expected-note {{refers to class template member}}
187   void h() { g<X>(); } // expected-error {{no matching function}}
188 }
189