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
34 int n
= 32; // expected-note {{declared here}}
35 template<typename Z
> using T
= int[n
]; // expected-error {{variable length array declaration not allowed at file scope}} \
36 expected
-warning
{{variable length arrays in C
++ are a Clang extension
}} \
37 expected
-note
{{read of non
-const variable
'n' is
not allowed in a constant expression
}}
40 template<typename Z
> using U
= int[m
];
41 template<typename Z
> using U
= int[42]; // expected-note {{previous definition}}
42 template<typename Z
> using U
= int; // expected-error {{type alias template redefinition with different types ('int' vs 'int[42]')}}
45 namespace RedeclFunc
{
47 template<typename Z
> using T
= int;
48 T
<char> f(int, char **); // ok
51 namespace LookupFilter
{
52 namespace N
{ template<typename U
> using S
= int; }
54 template<typename U
> using S
= S
<U
>*; // ok
57 namespace InFunctions
{
58 template<typename
...T
> struct S0
{
59 template<typename Z
> using U
= T
*; // expected-error {{declaration type contains unexpanded parameter pack 'T'}}
63 template<typename Z
> using T1
= int;
64 template<typename Z
> using T2
= int[-1]; // expected-error {{array size is negative}}
65 template<typename
...T
> struct S3
{ // expected-note {{template parameter is declared here}}
66 template<typename Z
> using T
= int; // expected-error {{declaration of 'T' shadows template parameter}}
68 template<typename Z
> using Z
= Z
;
71 namespace ClassNameRedecl
{
73 template<typename U
> using C0
= int; // expected-error {{member 'C0' has the same name as its class}}
76 template<typename U
> using C1
= C1
; // expected-error {{member 'C1' has the same name as its class}}
79 template<typename U
> using C0
= C1
; // ok
81 template<typename
...T
> class C3
{
82 template<typename U
> using f
= T
; // expected-error {{declaration type contains unexpanded parameter pack 'T'}}
84 template<typename T
> class C4
{ // expected-note {{template parameter is declared here}}
85 template<typename U
> using T
= int; // expected-error {{declaration of 'T' shadows template parameter}}
88 class c
; // expected-note {{previous definition}}
89 template<typename U
> using c
= int; // expected-error {{redefinition of 'c' as different kind of symbol}}
90 class d
; // expected-note {{previous definition}}
91 template<typename U
> using d
= d
; // expected-error {{redefinition of 'd' as different kind of symbol}}
94 class c
{ template<typename U
> using C6
= int; }; // ok
99 template<typename T
> using X
= CtorDtorName
;
100 X
<int>(); // expected-error {{expected member name}}
101 ~X
<int>(); // expected-error {{destructor cannot be declared using a type alias}}
105 template<typename Z
> using S
= struct { int n
; }; // expected-error {{cannot be defined}}
106 template<typename Z
> using T
= class { int n
; }; // expected-error {{cannot be defined}}
107 template<typename Z
> using U
= enum { a
, b
, c
}; // expected-error {{cannot be defined}}
108 template<typename Z
> using V
= struct V
{ int n
; }; // expected-error {{'TagName::V' cannot be defined in a type alias template}}
111 namespace StdExample
{
112 template<typename T
, typename U
> struct pair
;
114 template<typename T
> using handler_t
= void (*)(T
);
115 extern handler_t
<int> ignore
;
116 extern void (*ignore
)(int);
117 // FIXME: we recover as if cell is an undeclared variable template
118 template<typename T
> using cell
= pair
<T
*, cell
<T
>*>; // expected-error {{use of undeclared identifier 'cell'}} expected-error {{expected expression}}
123 template<typename Z
> using U
= int; // expected-note {{declared private here}}
125 C0::U
<int> v
; // expected-error {{'U' is a private member}}
128 template<typename Z
> using U
= int;
134 template<typename Z
> using V
= void;
136 V
<char> g(V
<double>); // ok (DR577)
140 template<typename T
, typename U
> struct S
;
141 template<typename T
> template<typename U
> using SS
= S
<T
, U
>; // expected-error {{extraneous template parameter list in alias template declaration}}
146 template<bool> struct enable_if
; // expected-note 2{{here}}
147 template<> struct enable_if
<true> { using type
= void; };
149 template<typename T
> struct is_enum
{ static constexpr bool value
= __is_enum(T
); };
151 template<typename T
> using EnableIf
= typename enable_if
<T::value
>::type
; // expected-error {{undefined template}}
152 template<typename T
> using DisableIf
= typename enable_if
<!T::value
>::type
; // expected-error {{undefined template}}
154 template<typename T
> EnableIf
<is_enum
<T
>> f();
155 template<typename T
> DisableIf
<is_enum
<T
>> f();
164 template<typename T
, typename U
= EnableIf
<is_enum
<T
>>> struct fail1
{}; // expected-note {{here}}
165 template<typename T
> struct fail2
: DisableIf
<is_enum
<T
>> {}; // expected-note {{here}}
167 fail1
<int> f1
; // expected-note {{here}}
168 fail2
<E
> f2
; // expected-note {{here}}
179 static_assert(__is_same(S
<3>::U
, X
[2]), ""); // expected-error {{static assertion failed}}
186 template <class T
, class = void_t
<typename
T::wait_what
>>
187 int sfinae_me() { return 0; } // expected-note{{candidate template ignored: substitution failure}}
189 int g
= sfinae_me
<int>(); // expected-error{{no matching function for call to 'sfinae_me'}}
192 namespace NullExceptionDecl
{
193 template<int... I
> auto get
= []() { try { } catch(...) {}; return I
; }; // expected-error{{initializer contains unexpanded parameter pack 'I'}}