1 // RUN: %clang_cc1 -verify -std=c++14 -fcxx-exceptions %s
3 namespace RedeclAliasTypedef
{
4 template<typename U
> using T
= int;
5 template<typename U
> using T
= int;
6 template<typename U
> using T
= T
<U
>;
9 namespace IllegalTypeIds
{
10 template<typename U
> using A
= void(int n
= 0); // expected-error {{default arguments can only be specified for parameters in a function declaration}}
11 template<typename U
> using B
= inline void(int n
); // expected-error {{type name does not allow function specifier}}
12 template<typename U
> using C
= virtual void(int n
); // expected-error {{type name does not allow function specifier}}
13 template<typename U
> using D
= explicit void(int n
); // expected-error {{type name does not allow function specifier}}
14 template<typename U
> using E
= void(int n
) throw(); // expected-error {{exception specifications are not allowed in type aliases}}
15 template<typename U
> using F
= void(*)(int n
) &&; // expected-error {{pointer to function type cannot have '&&' qualifier}}
16 template<typename U
> using G
= __thread
void(int n
); // expected-error {{type name does not allow storage class to be specified}}
17 template<typename U
> using H
= constexpr int; // expected-error {{type name does not allow constexpr specifier}}
19 template<typename U
> using Y
= void(int n
); // ok
20 template<typename U
> using Z
= void(int n
) &&; // ok
23 namespace IllegalSyntax
{
24 template<typename Z
> using ::T
= void(int n
); // expected-error {{name defined in alias declaration must be an identifier}}
25 template<typename Z
> using operator int = void(int n
); // expected-error {{name defined in alias declaration must be an identifier}}
26 template<typename Z
> using typename U
= void; // expected-error {{name defined in alias declaration must be an identifier}}
27 template<typename Z
> using typename ::V
= void(int n
); // expected-error {{name defined in alias declaration must be an identifier}}
28 template<typename Z
> using typename ::operator bool = void(int n
); // expected-error {{name defined in alias declaration must be an identifier}}
31 namespace VariableLengthArrays
{
32 template<typename Z
> using T
= int[42]; // ok
35 template<typename Z
> using T
= int[n
]; // expected-error {{variable length array declaration not allowed at file scope}}
38 template<typename Z
> using U
= int[m
];
39 template<typename Z
> using U
= int[42]; // expected-note {{previous definition}}
40 template<typename Z
> using U
= int; // expected-error {{type alias template redefinition with different types ('int' vs 'int[42]')}}
43 namespace RedeclFunc
{
45 template<typename Z
> using T
= int;
46 T
<char> f(int, char **); // ok
49 namespace LookupFilter
{
50 namespace N
{ template<typename U
> using S
= int; }
52 template<typename U
> using S
= S
<U
>*; // ok
55 namespace InFunctions
{
56 template<typename
...T
> struct S0
{
57 template<typename Z
> using U
= T
*; // expected-error {{declaration type contains unexpanded parameter pack 'T'}}
61 template<typename Z
> using T1
= int;
62 template<typename Z
> using T2
= int[-1]; // expected-error {{array size is negative}}
63 template<typename
...T
> struct S3
{ // expected-note {{template parameter is declared here}}
64 template<typename Z
> using T
= int; // expected-error {{declaration of 'T' shadows template parameter}}
66 template<typename Z
> using Z
= Z
;
69 namespace ClassNameRedecl
{
71 template<typename U
> using C0
= int; // expected-error {{member 'C0' has the same name as its class}}
74 template<typename U
> using C1
= C1
; // expected-error {{member 'C1' has the same name as its class}}
77 template<typename U
> using C0
= C1
; // ok
79 template<typename
...T
> class C3
{
80 template<typename U
> using f
= T
; // expected-error {{declaration type contains unexpanded parameter pack 'T'}}
82 template<typename T
> class C4
{ // expected-note {{template parameter is declared here}}
83 template<typename U
> using T
= int; // expected-error {{declaration of 'T' shadows template parameter}}
86 class c
; // expected-note {{previous definition}}
87 template<typename U
> using c
= int; // expected-error {{redefinition of 'c' as different kind of symbol}}
88 class d
; // expected-note {{previous definition}}
89 template<typename U
> using d
= d
; // expected-error {{redefinition of 'd' as different kind of symbol}}
92 class c
{ template<typename U
> using C6
= int; }; // ok
97 template<typename T
> using X
= CtorDtorName
;
98 X
<int>(); // expected-error {{expected member name}}
99 ~X
<int>(); // expected-error {{destructor cannot be declared using a type alias}}
103 template<typename Z
> using S
= struct { int n
; }; // expected-error {{cannot be defined}}
104 template<typename Z
> using T
= class { int n
; }; // expected-error {{cannot be defined}}
105 template<typename Z
> using U
= enum { a
, b
, c
}; // expected-error {{cannot be defined}}
106 template<typename Z
> using V
= struct V
{ int n
; }; // expected-error {{'TagName::V' cannot be defined in a type alias template}}
109 namespace StdExample
{
110 template<typename T
, typename U
> struct pair
;
112 template<typename T
> using handler_t
= void (*)(T
);
113 extern handler_t
<int> ignore
;
114 extern void (*ignore
)(int);
115 // FIXME: we recover as if cell is an undeclared variable template
116 template<typename T
> using cell
= pair
<T
*, cell
<T
>*>; // expected-error {{use of undeclared identifier 'cell'}} expected-error {{expected expression}}
121 template<typename Z
> using U
= int; // expected-note {{declared private here}}
123 C0::U
<int> v
; // expected-error {{'U' is a private member}}
126 template<typename Z
> using U
= int;
132 template<typename Z
> using V
= void;
134 V
<char> g(V
<double>); // ok (DR577)
138 template<typename T
, typename U
> struct S
;
139 template<typename T
> template<typename U
> using SS
= S
<T
, U
>; // expected-error {{extraneous template parameter list in alias template declaration}}
144 template<bool> struct enable_if
; // expected-note 2{{here}}
145 template<> struct enable_if
<true> { using type
= void; };
147 template<typename T
> struct is_enum
{ static constexpr bool value
= __is_enum(T
); };
149 template<typename T
> using EnableIf
= typename enable_if
<T::value
>::type
; // expected-error {{undefined template}}
150 template<typename T
> using DisableIf
= typename enable_if
<!T::value
>::type
; // expected-error {{undefined template}}
152 template<typename T
> EnableIf
<is_enum
<T
>> f();
153 template<typename T
> DisableIf
<is_enum
<T
>> f();
162 template<typename T
, typename U
= EnableIf
<is_enum
<T
>>> struct fail1
{}; // expected-note {{here}}
163 template<typename T
> struct fail2
: DisableIf
<is_enum
<T
>> {}; // expected-note {{here}}
165 fail1
<int> f1
; // expected-note {{here}}
166 fail2
<E
> f2
; // expected-note {{here}}
177 static_assert(__is_same(S
<3>::U
, X
[2]), ""); // expected-error {{static_assert failed}}
184 template <class T
, class = void_t
<typename
T::wait_what
>>
185 int sfinae_me() { return 0; } // expected-note{{candidate template ignored: substitution failure}}
187 int g
= sfinae_me
<int>(); // expected-error{{no matching function for call to 'sfinae_me'}}
190 namespace NullExceptionDecl
{
191 template<int... I
> auto get
= []() { try { } catch(...) {}; return I
; }; // expected-error{{initializer contains unexpanded parameter pack 'I'}}