brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.8 KiB · cc5a406 Raw
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