295 lines · cpp
1// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fexceptions -fcxx-exceptions -verify=expected,pre20 %s2// RUN: %clang_cc1 -std=c++2a -fsyntax-only -fexceptions -fcxx-exceptions -verify=expected,post20 %s3 4template<typename... Types> struct tuple;5template<int I> struct int_c;6 7template<typename T>8struct identity {9 typedef T type;10};11 12template<typename T, typename U>13struct is_same {14 static const bool value = false;15};16 17template<typename T>18struct is_same<T, T> {19 static const bool value = true;20};21 22// FIXME: Several more bullets to go23 24// In a function parameter pack, the pattern is the parameter-declaration25// without the ellipsis.26namespace PR11850 {27 template<typename ...T> struct S {28 int f(T...a, int b) { return b; }29 };30 S<> s;31 S<int*, char, const double&> t;32 int k = s.f(0);33 int l = t.f(&k, 'x', 5.9, 4);34 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...);39 };40 };41 };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);48 49 int &f();50 char &f(void*);51 template<typename ...A> struct U {52 template<typename ...B> struct V {53 auto g(A...a, B...b) -> decltype(f(a...));54 };55 };56 U<>::V<int*> v0;57 U<int*>::V<> v1;58 int &v0f = v0.g(0);59 char &v1f = v1.g(0);60}61namespace PR12096 {62 void Foo(int) {}63 void Foo(int, int) = delete;64 template<typename ...Args> struct Var {65 Var(const Args &...args, int *) { Foo(args...); }66 };67 Var<int> var(1, 0);68}69 70// In an initializer-list (8.5); the pattern is an initializer-clause.71// Note: this also covers expression-lists, since expression-list is72// just defined as initializer-list.73void five_args(int, int, int, int, int); // expected-note{{candidate function not viable: requires 5 arguments, but 6 were provided}}74 75template<int ...Values>76void 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'}}79}80 81template void initializer_list_expansion<1, 2, 3, 4, 5>();82template 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}}83 84namespace PR8977 {85 struct A { };86 template<typename T, typename... Args> void f(Args... args) {87 // An empty expression-list performs value initialization.88 constexpr T t(args...);89 };90 91 template void f<A>();92}93 94// In a base-specifier-list (Clause 10); the pattern is a base-specifier.95template<typename ...Mixins>96struct HasMixins : public Mixins... { 97 HasMixins();98 HasMixins(const HasMixins&);99 HasMixins(int i);100};101 102struct 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}}105struct 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}}108struct C { };109struct D { };110 111A *checkA = new HasMixins<A, B, C, D>;112B *checkB = new HasMixins<A, B, C, D>;113D *checkD = new HasMixins<A, B, C, D>;114C *checkC = new HasMixins<A, B, D>; // expected-error{{cannot initialize a variable of type 'C *' with an rvalue of type 'HasMixins<A, B, D> *'}}115HasMixins<> *checkNone = new HasMixins<>;116 117template<typename Mixins>118struct BrokenMixins : public Mixins... { }; // expected-error{{pack expansion does not contain any unexpanded parameter packs}}119 120// In a mem-initializer-list (12.6.2); the pattern is a mem-initializer.121template<typename ...Mixins>122HasMixins<Mixins...>::HasMixins(): Mixins()... { }123 124template<typename ...Mixins>125HasMixins<Mixins...>::HasMixins(const HasMixins &other): Mixins(other)... { }126 127template<typename ...Mixins>128HasMixins<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}}133 134void test_has_mixins() {135 HasMixins<A, B> ab;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}}138}139 140template<typename T>141struct X {142 T member;143 144 X() : member()... { } // expected-error{{pack expansion for initialization of member 'member'}}145};146 147// There was a bug in the delayed parsing code for the148// following case.149template<typename ...T>150struct DelayedParseTest : T...151{152 int a;153 DelayedParseTest(T... i) : T{i}..., a{10} {}154};155 156 157// In a template-argument-list (14.3); the pattern is a template-argument.158template<typename ...Types>159struct tuple_of_refs {160 typedef tuple<Types& ...> types;161};162 163tuple<int&, float&> *t_int_ref_float_ref;164tuple_of_refs<int&, float&>::types *t_int_ref_float_ref_2 = t_int_ref_float_ref;165 166template<typename ...Types>167struct extract_nested_types {168 typedef tuple<typename Types::type...> types;169};170 171tuple<int, float> *t_int_float;172extract_nested_types<identity<int>, identity<float> >::types *t_int_float_2 173 = t_int_float;174 175template<int ...N>176struct tuple_of_ints {177 typedef tuple<int_c<N>...> type;178};179 180int 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];183 184#if __cplusplus < 201703L185// In a dynamic-exception-specification (15.4); the pattern is a type-id.186template<typename ...Types>187struct f_with_except {188 virtual void f() throw(Types...); // expected-note{{overridden virtual function is here}}189};190 191struct check_f_with_except_1 : f_with_except<int, float> {192 virtual void f() throw(int, float);193};194 195struct check_f_with_except_2 : f_with_except<int, float> {196 virtual void f() throw(int);197};198 199struct 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}}201};202#endif203 204namespace PackExpansionWithinLambda {205 void swallow(...);206 template<typename ...T, typename ...U> void f(U ...u) {207 swallow([=] {208 // C++17 [temp.variadic]p4:209 // Pack expansions can occur in the following contexts:210 211 // - in a function parameter pack212 void g(T...);213 214#if __cplusplus >= 201703L215 struct A : T... {216 // - in a using-declaration217 using T::x...;218 using typename T::U...;219 };220#endif221 222#if __cplusplus > 201703L223 // - in a template parameter pack that is a pack expansion224 swallow([]<T *...v, template<T *> typename ...W>(W<v> ...wv) { });225#endif226 227 // - in an initializer-list228 int arr[] = {T().x...};229 230 // - in a base-specifier-list231 struct B : T... {232 // - in a mem-initializer-list233 B() : T{0}... {}234 };235 236 // - in a template-argument-list237 f<T...>();238 239 // - in an attribute-list240 // FIXME: We do not support any such attributes yet.241 242 // - in an alignment-specifier243 alignas(T...) int y;244 245 // - in a capture-list246 [](T ...t) { [t...]{}(); } (T()...);247 248 // - in a sizeof... expression249 const int k1 = sizeof...(T);250 251#if __cplusplus >= 201703L252 // - in a fold-expression253 const int k2 = ((sizeof(T)/sizeof(T)) + ...);254 255 static_assert(k1 == k2);256#endif257 258 // Trigger clang to look in here for unexpanded packs.259 U u;260 } ...);261 }262 263 template<typename ...T> void nested() {264 swallow([=] {265 [](T ...t) { [t]{}(); } (T()...); // expected-error {{unexpanded parameter pack 't'}}266 }...); // expected-error {{does not contain any unexpanded}}267 }268 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 >= 201703L274 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'}}276#endif277 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'}}284 } (T()...); });285 }286 287 struct T { int x; using U = int; };288 void g() { f<T>(1, 2, 3); }289 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}}293 }294}295