1 // RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -verify %s
2 
3 template <typename T> struct A { // expected-note 38{{declared here}}
AA4   constexpr A() {}
AA5   constexpr A(int) {}
operator intA6   constexpr operator int() { return 0; }
7 };
8 A() -> A<int>;
9 A(int) -> A<int>;
10 
11 // Make sure we still correctly parse cases where a template can appear without arguments.
12 namespace template_template_arg {
13   template<template<typename> typename> struct X {};
14   template<typename> struct Y {};
15 
16   X<A> xa;
17   Y<A> ya; // expected-error {{requires template arguments}}
18   X<::A> xcca;
19   Y<::A> ycca; // expected-error {{requires template arguments}}
20   X<A*> xap; // expected-error {{requires template arguments}}
21   X<const A> xca; // expected-error {{requires template arguments}}
22   X<A const> xac; // expected-error {{requires template arguments}}
23   // FIXME: This should not parse as a template template argument due to the
24   // trailing attributes.
25   X<A [[]]> xa_attr;
26 
27   template<template<typename> typename = A> struct XD {};
28   template<typename = A> struct YD {}; // expected-error {{requires template arguments}}
29   template<template<typename> typename = ::A> struct XCCD {};
30   template<typename = ::A> struct YCCD {}; // expected-error {{requires template arguments}}
31 
32   // FIXME: replacing the invalid type with 'int' here is horrible
33   template <A a = A<int>()> class C { }; // expected-error {{requires template arguments}}
34   template<typename T = A> struct G { }; // expected-error {{requires template arguments}}
35 }
36 
37 namespace template_template_arg_pack {
38   template<template<typename> typename...> struct XP {};
39   template<typename...> struct YP {};
40 
41   struct Z { template<typename T> struct Q {}; }; // expected-note 2{{here}}
42 
43   template<typename T> using ZId = Z;
44 
45   template<typename ...Ts> struct A {
46     XP<ZId<Ts>::Q...> xe;
47     YP<ZId<Ts>::Q...> ye; // expected-error {{requires template arguments}}
48 
49     XP<ZId<Ts>::Q> xp; // expected-error {{unexpanded parameter pack}}
50     YP<ZId<Ts>::Q> yp; // expected-error {{requires template arguments}}
51   };
52 }
53 
54 namespace injected_class_name {
55   template<typename T> struct A {
56     A(T);
finjected_class_name::A57     void f(int) { // expected-note {{previous}}
58       A a = 1;
59       injected_class_name::A b = 1; // expected-note {{in instantiation of template class 'injected_class_name::A<int>'}}
60     }
61     void f(T); // expected-error {{multiple overloads of 'f' instantiate to the same signature 'void (int)}}
62   };
63   A<short> ai = 1;
64   A<double>::A b(1); // expected-error {{constructor name}}
65 }
66 
67 struct member {
68   A a; // expected-error {{requires template arguments}}
69   A *b; // expected-error {{requires template arguments}}
70   const A c; // expected-error {{requires template arguments}}
71 
72   void f() throw (A); // expected-error {{requires template arguments}}
73 
74   friend A; // expected-error {{requires template arguments; argument deduction not allowed in friend declaration}}
75 
76   operator A(); // expected-error {{requires template arguments; argument deduction not allowed in conversion function type}}
77 
78   static A x; // expected-error {{declaration of variable 'x' with deduced type 'A' requires an initializer}}
79   static constexpr A y = 0;
80 };
81 
82 namespace in_typedef {
83   typedef A *AutoPtr; // expected-error {{requires template arguments; argument deduction not allowed in typedef}}
84   typedef A (*PFun)(int a); // expected-error{{requires template arguments; argument deduction not allowed in typedef}}
85   typedef A Fun(int a) -> decltype(a + a); // expected-error{{requires template arguments; argument deduction not allowed in function return type}}
86 }
87 
88 namespace stmt {
g(A a)89   void g(A a) { // expected-error{{requires template arguments; argument deduction not allowed in function prototype}}
90     try { }
91     catch (A &a) { } // expected-error{{requires template arguments; argument deduction not allowed in exception declaration}}
92     catch (const A a) { } // expected-error{{requires template arguments; argument deduction not allowed in exception declaration}}
93     try { } catch (A a) { } // expected-error{{requires template arguments; argument deduction not allowed in exception declaration}}
94 
95     // FIXME: The standard only permits class template argument deduction in a
96     // simple-declaration or cast. We also permit it in conditions,
97     // for-range-declarations, member-declarations for static data members, and
98     // new-expressions, because not doing so would be bizarre.
99     A local = 0;
100     static A local_static = 0;
101     static thread_local A thread_local_static = 0;
102     if (A a = 0) {}
103     if (A a = 0; a) {}
104     switch (A a = 0) {} // expected-warning {{no case matching constant switch condition '0'}}
105     switch (A a = 0; a) {} // expected-warning {{no case matching constant switch condition '0'}}
106     for (A a = 0; a; /**/) {}
107     for (/**/; A a = 0; /**/) {}
108     while (A a = 0) {}
109     int arr[3];
110     for (A a : arr) {}
111   }
112 
113   namespace std {
114     class type_info;
115   }
116 }
117 
118 namespace expr {
119   template<typename T> struct U {};
j()120   void j() {
121     (void)typeid(A); // expected-error{{requires template arguments; argument deduction not allowed here}}
122     (void)sizeof(A); // expected-error{{requires template arguments; argument deduction not allowed here}}
123     (void)__alignof(A); // expected-error{{requires template arguments; argument deduction not allowed here}}
124 
125     U<A> v; // expected-error {{requires template arguments}}
126 
127     int n;
128     (void)dynamic_cast<A&>(n); // expected-error{{requires template arguments; argument deduction not allowed here}}
129     (void)static_cast<A*>(&n); // expected-error{{requires template arguments; argument deduction not allowed here}}
130     (void)reinterpret_cast<A*>(&n); // expected-error{{requires template arguments; argument deduction not allowed here}}
131     (void)const_cast<A>(n); // expected-error{{requires template arguments; argument deduction not allowed here}}
132     (void)*(A*)(&n); // expected-error{{requires template arguments; argument deduction not allowed here}}
133     (void)(A)(n); // expected-error{{requires template arguments; argument deduction not allowed here}}
134     (void)(A){n}; // expected-error{{requires template arguments; argument deduction not allowed here}}
135 
136     (void)A(n);
137     (void)A{n};
138     (void)new A(n);
139     (void)new A{n};
140     (void)new A;
141   }
142 }
143 
144 namespace decl {
145   enum E : A {}; // expected-error{{requires template arguments; argument deduction not allowed here}}
146   struct F : A {}; // expected-error{{expected class name}}
147 
148   using B = A; // expected-error{{requires template arguments}}
149 
150   auto k() -> A; // expected-error{{requires template arguments}}
151 
152   A a;
153   A b = 0;
154   const A c = 0;
155   A (parens) = 0; // expected-error {{cannot use parentheses when declaring variable with deduced class template specialization type}}
156   A *p = 0; // expected-error {{cannot form pointer to deduced class template specialization type}}
157   A &r = *p; // expected-error {{cannot form reference to deduced class template specialization type}}
158   A arr[3] = 0; // expected-error {{cannot form array of deduced class template specialization type}}
159   A F::*pm = 0; // expected-error {{cannot form pointer to deduced class template specialization type}}
160   A (*fp)() = 0; // expected-error {{cannot form function returning deduced class template specialization type}}
161   A [x, y] = 0; // expected-error {{cannot be declared with type 'A'}} expected-error {{type 'A<int>' decomposes into 0 elements, but 2 names were provided}}
162 }
163 
164 namespace typename_specifier {
165   struct F {};
166 
e()167   void e() {
168     (void) typename ::A(0);
169     (void) typename ::A{0};
170     new typename ::A(0);
171     new typename ::A{0};
172     typename ::A a = 0;
173     const typename ::A b = 0;
174     if (typename ::A a = 0) {}
175     for (typename ::A a = 0; typename ::A b = 0; /**/) {}
176 
177     (void)(typename ::A)(0); // expected-error{{requires template arguments; argument deduction not allowed here}}
178     (void)(typename ::A){0}; // expected-error{{requires template arguments; argument deduction not allowed here}}
179   }
180   typename ::A a = 0;
181   const typename ::A b = 0;
182   typename ::A (parens) = 0; // expected-error {{cannot use parentheses when declaring variable with deduced class template specialization type}}
183   typename ::A *p = 0; // expected-error {{cannot form pointer to deduced class template specialization type}}
184   typename ::A &r = *p; // expected-error {{cannot form reference to deduced class template specialization type}}
185   typename ::A arr[3] = 0; // expected-error {{cannot form array of deduced class template specialization type}}
186   typename ::A F::*pm = 0; // expected-error {{cannot form pointer to deduced class template specialization type}}
187   typename ::A (*fp)() = 0; // expected-error {{cannot form function returning deduced class template specialization type}}
188   typename ::A [x, y] = 0; // expected-error {{cannot be declared with type 'typename ::A'}} expected-error {{type 'typename ::A<int>' (aka 'A<int>') decomposes into 0}}
189 
190   struct X { template<typename T> struct A { A(T); }; }; // expected-note 8{{declared here}}
191 
f()192   template<typename T> void f() {
193     (void) typename T::A(0);
194     (void) typename T::A{0};
195     new typename T::A(0);
196     new typename T::A{0};
197     typename T::A a = 0;
198     const typename T::A b = 0;
199     if (typename T::A a = 0) {} // expected-error {{value of type 'typename X::A<int>' (aka 'typename_specifier::X::A<int>') is not contextually convertible to 'bool'}}
200     for (typename T::A a = 0; typename T::A b = 0; /**/) {} // expected-error {{value of type 'typename X::A<int>' (aka 'typename_specifier::X::A<int>') is not contextually convertible to 'bool'}}
201 
202     {(void)(typename T::A)(0);} // expected-error{{refers to class template member}}
203     {(void)(typename T::A){0};} // expected-error{{refers to class template member}}
204     {typename T::A (parens) = 0;} // expected-error {{refers to class template member in 'typename_specifier::X'; argument deduction not allowed here}}
205     // expected-warning@-1 {{disambiguated as redundant parentheses around declaration of variable named 'parens'}} expected-note@-1 {{add a variable name}} expected-note@-1{{remove parentheses}} expected-note@-1 {{add enclosing parentheses}}
206     {typename T::A *p = 0;} // expected-error {{refers to class template member}}
207     {typename T::A &r = *p;} // expected-error {{refers to class template member}}
208     {typename T::A arr[3] = 0;} // expected-error {{refers to class template member}}
209     {typename T::A F::*pm = 0;} // expected-error {{refers to class template member}}
210     {typename T::A (*fp)() = 0;} // expected-error {{refers to class template member}}
211     {typename T::A [x, y] = 0;} // expected-error {{cannot be declared with type 'typename T::A'}} expected-error {{type 'typename X::A<int>' (aka 'typename_specifier::X::A<int>') decomposes into 0}}
212   }
213   template void f<X>(); // expected-note {{instantiation of}}
214 
215   template<typename T> void g(typename T::A = 0); // expected-note {{refers to class template member}}
h()216   void h() { g<X>(); } // expected-error {{no matching function}}
217 }
218 
219 namespace parenthesized {
220   template<typename T> struct X { X(T); };
__anond59a3dfe0102null221   auto n = (X([]{}));
222 }
223 
224 namespace within_template_arg_list {
Xwithin_template_arg_list::X225   template<typename T> struct X { constexpr X(T v) : v(v) {} T v; };
226   template<int N = X(1).v> struct Y {};
227   using T = Y<>;
228   using T = Y<X(1).v>;
229   using T = Y<within_template_arg_list::X(1).v>;
230 
231   template<int ...N> struct Z { Y<X(N)...> y; };
232 }
233