1 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -fexceptions -fcxx-exceptions -verify %s 2 // RUN: %clang_cc1 -std=c++2a -fsyntax-only -fexceptions -fcxx-exceptions -verify %s 3 4 template<typename... Types> struct tuple; 5 template<int I> struct int_c; 6 7 template<typename T> 8 struct identity { 9 typedef T type; 10 }; 11 12 template<typename T, typename U> 13 struct is_same { 14 static const bool value = false; 15 }; 16 17 template<typename T> 18 struct is_same<T, T> { 19 static const bool value = true; 20 }; 21 22 // FIXME: Several more bullets to go 23 24 // In a function parameter pack, the pattern is the parameter-declaration 25 // without the ellipsis. 26 namespace 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 } 61 namespace 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 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}} 74 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'}} 79 } 80 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}} 83 84 namespace 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. 95 template<typename ...Mixins> 96 struct HasMixins : public Mixins... { 97 HasMixins(); 98 HasMixins(const HasMixins&); 99 HasMixins(int i); 100 }; 101 102 struct A { }; // expected-note{{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int' to 'const A' for 1st argument}} \ 103 // expected-note{{candidate constructor (the implicit move constructor) not viable: no known conversion from 'int' to 'A' for 1st argument}} \ 104 // expected-note{{candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided}} 105 struct B { }; 106 struct C { }; 107 struct D { }; 108 109 A *checkA = new HasMixins<A, B, C, D>; 110 B *checkB = new HasMixins<A, B, C, D>; 111 D *checkD = new HasMixins<A, B, C, D>; 112 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> *'}} 113 HasMixins<> *checkNone = new HasMixins<>; 114 115 template<typename Mixins> 116 struct BrokenMixins : public Mixins... { }; // expected-error{{pack expansion does not contain any unexpanded parameter packs}} 117 118 // In a mem-initializer-list (12.6.2); the pattern is a mem-initializer. 119 template<typename ...Mixins> 120 HasMixins<Mixins...>::HasMixins(): Mixins()... { } 121 122 template<typename ...Mixins> 123 HasMixins<Mixins...>::HasMixins(const HasMixins &other): Mixins(other)... { } 124 125 template<typename ...Mixins> 126 HasMixins<Mixins...>::HasMixins(int i): Mixins(i)... { } // expected-error{{no matching constructor for initialization of 'A'}} 127 128 void test_has_mixins() { 129 HasMixins<A, B> ab; 130 HasMixins<A, B> ab2 = ab; 131 HasMixins<A, B> ab3(17); // expected-note{{in instantiation of member function 'HasMixins<A, B>::HasMixins' requested here}} 132 } 133 134 template<typename T> 135 struct X { 136 T member; 137 138 X() : member()... { } // expected-error{{pack expansion for initialization of member 'member'}} 139 }; 140 141 // There was a bug in the delayed parsing code for the 142 // following case. 143 template<typename ...T> 144 struct DelayedParseTest : T... 145 { 146 int a; 147 DelayedParseTest(T... i) : T{i}..., a{10} {} 148 }; 149 150 151 // In a template-argument-list (14.3); the pattern is a template-argument. 152 template<typename ...Types> 153 struct tuple_of_refs { 154 typedef tuple<Types& ...> types; 155 }; 156 157 tuple<int&, float&> *t_int_ref_float_ref; 158 tuple_of_refs<int&, float&>::types *t_int_ref_float_ref_2 = t_int_ref_float_ref; 159 160 template<typename ...Types> 161 struct extract_nested_types { 162 typedef tuple<typename Types::type...> types; 163 }; 164 165 tuple<int, float> *t_int_float; 166 extract_nested_types<identity<int>, identity<float> >::types *t_int_float_2 167 = t_int_float; 168 169 template<int ...N> 170 struct tuple_of_ints { 171 typedef tuple<int_c<N>...> type; 172 }; 173 174 int check_temp_arg_1[is_same<tuple_of_ints<1, 2, 3, 4, 5>::type, 175 tuple<int_c<1>, int_c<2>, int_c<3>, int_c<4>, 176 int_c<5>>>::value? 1 : -1]; 177 178 #if __cplusplus < 201703L 179 // In a dynamic-exception-specification (15.4); the pattern is a type-id. 180 template<typename ...Types> 181 struct f_with_except { 182 virtual void f() throw(Types...); // expected-note{{overridden virtual function is here}} 183 }; 184 185 struct check_f_with_except_1 : f_with_except<int, float> { 186 virtual void f() throw(int, float); 187 }; 188 189 struct check_f_with_except_2 : f_with_except<int, float> { 190 virtual void f() throw(int); 191 }; 192 193 struct check_f_with_except_3 : f_with_except<int, float> { 194 virtual void f() throw(int, float, double); // expected-error{{exception specification of overriding function is more lax than base version}} 195 }; 196 #endif 197 198 namespace PackExpansionWithinLambda { 199 void swallow(...); 200 template<typename ...T, typename ...U> void f(U ...u) { 201 swallow([=] { 202 // C++17 [temp.variadic]p4: 203 // Pack expansions can occur in the following contexts: 204 205 // - in a function parameter pack 206 void g(T...); 207 208 #if __cplusplus >= 201703L 209 struct A : T... { 210 // - in a using-declaration 211 using T::x...; 212 using typename T::U...; 213 }; 214 #endif 215 216 // - in a template parameter pack that is a pack expansion 217 // FIXME: We do not support any way to reach this case yet. 218 219 // - in an initializer-list 220 int arr[] = {T().x...}; 221 222 // - in a base-specifier-list 223 struct B : T... { 224 // - in a mem-initializer-list 225 B() : T{0}... {} 226 }; 227 228 // - in a template-argument-list 229 f<T...>(); 230 231 // - in an attribute-list 232 // FIXME: We do not support any such attributes yet. 233 234 // - in an alignment-specifier 235 alignas(T...) int y; 236 237 // - in a capture-list 238 [](T ...t) { [t...]{}(); } (T()...); 239 240 // - in a sizeof... expression 241 const int k1 = sizeof...(T); 242 243 #if __cplusplus >= 201703L 244 // - in a fold-expression 245 const int k2 = ((sizeof(T)/sizeof(T)) + ...); 246 247 static_assert(k1 == k2); 248 #endif 249 250 // Trigger clang to look in here for unexpanded packs. 251 U u; 252 } ...); 253 } 254 255 template<typename ...T> void nested() { 256 swallow([=] { 257 [](T ...t) { [t]{}(); } (T()...); // expected-error {{unexpanded parameter pack 't'}} 258 }...); // expected-error {{does not contain any unexpanded}} 259 } 260 261 template <typename ...T> void g() { 262 // Check that we do detect the above cases when the pack is not expanded. 263 swallow([=] { void h(T); }); // expected-error {{unexpanded parameter pack 'T'}} 264 swallow([=] { struct A : T {}; }); // expected-error {{unexpanded parameter pack 'T'}} 265 #if __cplusplus >= 201703L 266 swallow([=] { struct A : T... { using T::x; }; }); // expected-error {{unexpanded parameter pack 'T'}} 267 swallow([=] { struct A : T... { using typename T::U; }; }); // expected-error {{unexpanded parameter pack 'T'}} 268 #endif 269 270 swallow([=] { int arr[] = {T().x}; }); // expected-error {{unexpanded parameter pack 'T'}} 271 swallow([=] { struct B : T... { B() : T{0} {} }; }); // expected-error {{unexpanded parameter pack 'T'}} 272 swallow([=] { f<T>(); }); // expected-error {{unexpanded parameter pack 'T'}} 273 swallow([=] { alignas(T) int y; }); // expected-error {{unexpanded parameter pack 'T'}} 274 swallow([=] { [](T ...t) { 275 [t]{}(); // expected-error {{unexpanded parameter pack 't'}} 276 } (T()...); }); 277 } 278 279 struct T { int x; using U = int; }; 280 void g() { f<T>(1, 2, 3); } 281 282 template<typename ...T, typename ...U> void pack_in_lambda(U ...u) { // expected-note {{here}} 283 // FIXME: Move this test into 'f' above once we support this syntax. 284 []<T *...v, template<T *> typename ...U>(U<v> ...uv) {}; // expected-error {{expected body of lambda}} expected-error {{does not refer to a value}} 285 } 286 287 template<typename ...T> void pack_expand_attr() { 288 // FIXME: Move this test into 'f' above once we support this. 289 [[gnu::aligned(alignof(T))...]] int x; // expected-error {{cannot be used as an attribute pack}} expected-error {{unexpanded}} 290 } 291 } 292