1 // RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -verify %s
3 template <typename T
> struct A
{ // expected-note 38{{declared here}}
6 constexpr operator int() { return 0; }
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
{};
17 Y
<A
> ya
; // expected-error {{requires template arguments}}
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.
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}}
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}}
37 namespace template_template_arg_pack
{
38 template<template<typename
> typename
...> struct XP
{};
39 template<typename
...> struct YP
{};
41 struct Z
{ template<typename T
> struct Q
{}; }; // expected-note 2{{here}}
43 template<typename T
> using ZId
= Z
;
45 template<typename
...Ts
> struct A
{
47 YP
<ZId
<Ts
>::Q
...> ye
; // expected-error {{requires template arguments}}
49 XP
<ZId
<Ts
>::Q
> xp
; // expected-error {{unexpanded parameter pack}}
50 YP
<ZId
<Ts
>::Q
> yp
; // expected-error {{requires template arguments}}
54 namespace injected_class_name
{
55 template<typename T
> struct A
{
57 void f(int) { // expected-note {{previous}}
59 injected_class_name::A b
= 1; // expected-note {{in instantiation of template class 'injected_class_name::A<int>'}}
61 void f(T
); // expected-error {{multiple overloads of 'f' instantiate to the same signature 'void (int)}}
64 A
<double>::A
b(1); // expected-error {{constructor name}}
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}}
72 void f() throw (A
); // expected-error {{requires template arguments}}
74 friend A
; // expected-error {{requires template arguments; argument deduction not allowed in friend declaration}}
76 operator A(); // expected-error {{requires template arguments; argument deduction not allowed in conversion function type}}
78 static A x
; // expected-error {{declaration of variable 'x' with deduced type 'A' requires an initializer}}
79 static constexpr A y
= 0;
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}}
89 void g(A a
) { // expected-error{{requires template arguments; argument deduction not allowed in function prototype}}
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}}
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.
100 static A local_static
= 0;
101 static thread_local A thread_local_static
= 0;
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; /**/) {}
119 template<typename T
> struct U
{};
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}}
125 U
<A
> v
; // expected-error {{requires template arguments}}
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}}
145 enum E
: A
{}; // expected-error{{requires template arguments; argument deduction not allowed here}}
146 struct F
: A
{}; // expected-error{{expected class name}}
148 using B
= A
; // expected-error{{requires template arguments}}
150 auto k() -> A
; // expected-error{{requires template arguments}}
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}}
164 namespace typename_specifier
{
168 (void) typename ::A(0);
169 (void) typename ::A
{0};
173 const typename ::A b
= 0;
174 if (typename ::A a
= 0) {}
175 for (typename ::A a
= 0; typename ::A b
= 0; /**/) {}
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}}
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}}
190 struct X
{ template<typename T
> struct A
{ A(T
); }; }; // expected-note 8{{declared here}}
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};
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'}}
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}}
213 template void f
<X
>(); // expected-note {{instantiation of}}
215 template<typename T
> void g(typename
T::A
= 0); // expected-note {{refers to class template member}}
216 void h() { g
<X
>(); } // expected-error {{no matching function}}
219 namespace parenthesized
{
220 template<typename T
> struct X
{ X(T
); };
224 namespace within_template_arg_list
{
225 template<typename T
> struct X
{ constexpr X(T v
) : v(v
) {} T v
; };
226 template<int N
= X(1).v
> struct Y
{};
229 using T
= Y
<within_template_arg_list::X(1).v
>;
231 template<int ...N
> struct Z
{ Y
<X(N
)...> y
; };
235 // Ensure that we do not crash when parsing code which looks like an invalid
236 // deduction guide declaration.
237 template<class> struct B
; // expected-note 2{{template is declared here}}
239 B() noexcept(false); // expected-error {{deduction guide must be declared in the same scope as template 'PR49735::B'}} \
240 // expected-error {{deduction guide declaration without trailing return type}}
244 template <typename Ty
>
245 B() noexcept(false); // expected-error {{deduction guide must be declared in the same scope as template 'PR49735::B'}} \
246 // expected-error {{deduction guide declaration without trailing return type}}
252 template <typename T
> struct vector
{};
255 GH57495::vector
.d
; // expected-error {{cannot use dot operator on a type}}
262 template <class> struct pair
; // expected-note 3{{declared here}}
264 template <class T2
> pair() -> pair
<T2
>; // expected-error 2{{no template named 'pair'}} \
265 // expected-error {{deduction guide must be declared in the same scope}} \
266 // expected-error {{cannot be deduced}} \
267 // expected-note {{non-deducible template parameter 'T2'}}