1 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -fexceptions -fcxx-exceptions -verify=expected,pre20 %s
2 // RUN: %clang_cc1 -std=c++2a -fsyntax-only -fexceptions -fcxx-exceptions -verify=expected,post20 %s
4 template<typename
... Types
> struct tuple
;
5 template<int I
> struct int_c
;
12 template<typename T
, typename U
>
14 static const bool value
= false;
18 struct is_same
<T
, T
> {
19 static const bool value
= true;
22 // FIXME: Several more bullets to go
24 // In a function parameter pack, the pattern is the parameter-declaration
25 // without the ellipsis.
27 template<typename
...T
> struct S
{
28 int f(T
...a
, int b
) { return b
; }
31 S
<int*, char, const double&> t
;
33 int l
= t
.f(&k
, 'x', 5.9, 4);
35 template<typename
...As
> struct A
{
36 template<typename
...Bs
> struct B
{
37 template<typename
...Cs
> struct C
{
38 C(As
..., Bs
..., int &k
, Cs
...);
42 A
<>::B
<>::C
<> c000(k
);
43 A
<int>::B
<>::C
<int> c101(1, k
, 3);
44 A
<>::B
<int>::C
<int> c011(1, k
, 3);
45 A
<int>::B
<int>::C
<> c110(1, 2, k
);
46 A
<int, int>::B
<int, int>::C
<int, int> c222(1, 2, 3, 4, k
, 5, 6);
47 A
<int, int, int>::B
<>::C
<> c300(1, 2, 3, k
);
51 template<typename
...A
> struct U
{
52 template<typename
...B
> struct V
{
53 auto g(A
...a
, B
...b
) -> decltype(f(a
...));
63 void Foo(int, int) = delete;
64 template<typename
...Args
> struct Var
{
65 Var(const Args
&...args
, int *) { Foo(args
...); }
70 // In an initializer-list (8.5); the pattern is an initializer-clause.
71 // Note: this also covers expression-lists, since expression-list is
72 // just defined as initializer-list.
73 void five_args(int, int, int, int, int); // expected-note{{candidate function not viable: requires 5 arguments, but 6 were provided}}
75 template<int ...Values
>
76 void initializer_list_expansion() {
77 int values
[5] = { Values
... }; // expected-error{{excess elements in array initializer}}
78 five_args(Values
...); // expected-error{{no matching function for call to 'five_args'}}
81 template void initializer_list_expansion
<1, 2, 3, 4, 5>();
82 template void initializer_list_expansion
<1, 2, 3, 4, 5, 6>(); // expected-note{{in instantiation of function template specialization 'initializer_list_expansion<1, 2, 3, 4, 5, 6>' requested here}}
86 template<typename T
, typename
... Args
> void f(Args
... args
) {
87 // An empty expression-list performs value initialization.
88 constexpr T
t(args
...);
94 // In a base-specifier-list (Clause 10); the pattern is a base-specifier.
95 template<typename
...Mixins
>
96 struct HasMixins
: public Mixins
... {
98 HasMixins(const HasMixins
&);
102 struct A
{ }; // pre20-note{{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int' to 'const A' for 1st argument}} \
103 // pre20-note{{candidate constructor (the implicit move constructor) not viable: no known conversion from 'int' to 'A' for 1st argument}} \
104 // pre20-note{{candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided}}
105 struct B
{ }; // pre20-note{{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int' to 'const B' for 1st argument}} \
106 // pre20-note{{candidate constructor (the implicit move constructor) not viable: no known conversion from 'int' to 'B' for 1st argument}} \
107 // pre20-note{{candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided}}
111 A
*checkA
= new HasMixins
<A
, B
, C
, D
>;
112 B
*checkB
= new HasMixins
<A
, B
, C
, D
>;
113 D
*checkD
= new HasMixins
<A
, B
, C
, D
>;
114 C
*checkC
= new HasMixins
<A
, B
, D
>; // expected-error{{cannot initialize a variable of type 'C *' with an rvalue of type 'HasMixins<A, B, D> *'}}
115 HasMixins
<> *checkNone
= new HasMixins
<>;
117 template<typename Mixins
>
118 struct BrokenMixins
: public Mixins
... { }; // expected-error{{pack expansion does not contain any unexpanded parameter packs}}
120 // In a mem-initializer-list (12.6.2); the pattern is a mem-initializer.
121 template<typename
...Mixins
>
122 HasMixins
<Mixins
...>::HasMixins(): Mixins()... { }
124 template<typename
...Mixins
>
125 HasMixins
<Mixins
...>::HasMixins(const HasMixins
&other
): Mixins(other
)... { }
127 template<typename
...Mixins
>
128 HasMixins
<Mixins
...>::HasMixins(int i
): Mixins(i
)... { }
129 // pre20-error@-1 {{no matching constructor for initialization of 'A'}}
130 // pre20-error@-2 {{no matching constructor for initialization of 'B'}}
131 // post20-error@-3 {{excess elements in struct initializer}}
132 // post20-error@-4 {{excess elements in struct initializer}}
134 void test_has_mixins() {
136 HasMixins
<A
, B
> ab2
= ab
;
137 HasMixins
<A
, B
> ab3(17); // expected-note{{in instantiation of member function 'HasMixins<A, B>::HasMixins' requested here}}
144 X() : member()... { } // expected-error{{pack expansion for initialization of member 'member'}}
147 // There was a bug in the delayed parsing code for the
149 template<typename
...T
>
150 struct DelayedParseTest
: T
...
153 DelayedParseTest(T
... i
) : T
{i
}..., a
{10} {}
157 // In a template-argument-list (14.3); the pattern is a template-argument.
158 template<typename
...Types
>
159 struct tuple_of_refs
{
160 typedef tuple
<Types
& ...> types
;
163 tuple
<int&, float&> *t_int_ref_float_ref
;
164 tuple_of_refs
<int&, float&>::types
*t_int_ref_float_ref_2
= t_int_ref_float_ref
;
166 template<typename
...Types
>
167 struct extract_nested_types
{
168 typedef tuple
<typename
Types::type
...> types
;
171 tuple
<int, float> *t_int_float
;
172 extract_nested_types
<identity
<int>, identity
<float> >::types
*t_int_float_2
176 struct tuple_of_ints
{
177 typedef tuple
<int_c
<N
>...> type
;
180 int check_temp_arg_1
[is_same
<tuple_of_ints
<1, 2, 3, 4, 5>::type
,
181 tuple
<int_c
<1>, int_c
<2>, int_c
<3>, int_c
<4>,
182 int_c
<5>>>::value
? 1 : -1];
184 #if __cplusplus < 201703L
185 // In a dynamic-exception-specification (15.4); the pattern is a type-id.
186 template<typename
...Types
>
187 struct f_with_except
{
188 virtual void f() throw(Types
...); // expected-note{{overridden virtual function is here}}
191 struct check_f_with_except_1
: f_with_except
<int, float> {
192 virtual void f() throw(int, float);
195 struct check_f_with_except_2
: f_with_except
<int, float> {
196 virtual void f() throw(int);
199 struct check_f_with_except_3
: f_with_except
<int, float> {
200 virtual void f() throw(int, float, double); // expected-error{{exception specification of overriding function is more lax than base version}}
204 namespace PackExpansionWithinLambda
{
206 template<typename
...T
, typename
...U
> void f(U
...u
) {
208 // C++17 [temp.variadic]p4:
209 // Pack expansions can occur in the following contexts:
211 // - in a function parameter pack
214 #if __cplusplus >= 201703L
216 // - in a using-declaration
218 using typename
T::U
...;
222 #if __cplusplus > 201703L
223 // - in a template parameter pack that is a pack expansion
224 swallow([]<T
*...v
, template<T
*> typename
...W
>(W
<v
> ...wv
) { });
227 // - in an initializer-list
228 int arr
[] = {T().x
...};
230 // - in a base-specifier-list
232 // - in a mem-initializer-list
236 // - in a template-argument-list
239 // - in an attribute-list
240 // FIXME: We do not support any such attributes yet.
242 // - in an alignment-specifier
245 // - in a capture-list
246 [](T
...t
) { [t
...]{}(); } (T()...);
248 // - in a sizeof... expression
249 const int k1
= sizeof...(T
);
251 #if __cplusplus >= 201703L
252 // - in a fold-expression
253 const int k2
= ((sizeof(T
)/sizeof(T
)) + ...);
255 static_assert(k1
== k2
);
258 // Trigger clang to look in here for unexpanded packs.
263 template<typename
...T
> void nested() {
265 [](T
...t
) { [t
]{}(); } (T()...); // expected-error {{unexpanded parameter pack 't'}}
266 }...); // expected-error {{does not contain any unexpanded}}
269 template <typename
...T
> void g() {
270 // Check that we do detect the above cases when the pack is not expanded.
271 swallow([=] { void h(T
); }); // expected-error {{unexpanded parameter pack 'T'}}
272 swallow([=] { struct A
: T
{}; }); // expected-error {{unexpanded parameter pack 'T'}}
273 #if __cplusplus >= 201703L
274 swallow([=] { struct A
: T
... { using T::x
; }; }); // expected-error {{unexpanded parameter pack 'T'}}
275 swallow([=] { struct A
: T
... { using typename
T::U
; }; }); // expected-error {{unexpanded parameter pack 'T'}}
278 swallow([=] { int arr
[] = {T().x
}; }); // expected-error {{unexpanded parameter pack 'T'}}
279 swallow([=] { struct B
: T
... { B() : T
{0} {} }; }); // expected-error {{unexpanded parameter pack 'T'}}
280 swallow([=] { f
<T
>(); }); // expected-error {{unexpanded parameter pack 'T'}}
281 swallow([=] { alignas(T
) int y
; }); // expected-error {{unexpanded parameter pack 'T'}}
282 swallow([=] { [](T
...t
) {
283 [t
]{}(); // expected-error {{unexpanded parameter pack 't'}}
287 struct T
{ int x
; using U
= int; };
288 void g() { f
<T
>(1, 2, 3); }
290 template<typename
...T
> void pack_expand_attr() {
291 // FIXME: Move this test into 'f' above once we support this.
292 [[gnu::aligned(alignof(T
))...]] int x
; // expected-error {{cannot be used as an attribute pack}} expected-error {{unexpanded}}