// RUN: %clang_cc1 -std=c++2c -verify %s struct NotAPack; template typename Tp> void not_pack() { int i = 0; i...[0]; // expected-error {{'i' does not refer to the name of a parameter pack}} V...[0]; // expected-error {{'V' does not refer to the name of a parameter pack}} NotAPack...[0] a; // expected-error{{'NotAPack' does not refer to the name of a parameter pack}} T...[0] b; // expected-error{{'T' does not refer to the name of a parameter pack}} Tp...[0] c; // expected-error{{'Tp' does not refer to the name of a parameter pack}} } template typename Tp> void not_pack_arrays() { NotAPack...[0] a[1]; // expected-error{{'NotAPack' does not refer to the name of a parameter pack}} T...[0] b[1]; // expected-error{{'T' does not refer to the name of a parameter pack}} Tp...[0] c[1]; // expected-error{{'Tp' does not refer to the name of a parameter pack}} } template struct TTP; void test_errors() { not_pack(); not_pack_arrays(); } namespace invalid_indexes { int non_constant_index(); // expected-note 2{{declared here}} template int params(auto... p) { return p...[idx]; // #error-param-size } template int test_types() { T...[N] a; // #error-type-size } void test() { params<0>(); // expected-note{{here}} \ // expected-error@#error-param-size {{invalid index 0 for pack 'p' of size 0}} params<1>(0); // expected-note{{here}} \ // expected-error@#error-param-size {{invalid index 1 for pack 'p' of size 1}} params<-1>(0); // expected-note{{here}} \ // expected-error@#error-param-size {{invalid index -1 for pack 'p' of size 1}} test_types<-1>(); //expected-note {{in instantiation}} \ // expected-error@#error-type-size {{invalid index -1 for pack 'T' of size 0}} test_types<-1, int>(); //expected-note {{in instantiation}} \ // expected-error@#error-type-size {{invalid index -1 for pack 'T' of size 1}} test_types<0>(); //expected-note {{in instantiation}} \ // expected-error@#error-type-size {{invalid index 0 for pack 'T' of size 0}} test_types<1, int>(); //expected-note {{in instantiation}} \ // expected-error@#error-type-size {{invalid index 1 for pack 'T' of size 1}} } void invalid_indexes(auto... p) { p...[non_constant_index()]; // expected-error {{array size is not a constant expression}}\ // expected-note {{cannot be used in a constant expression}} const char* no_index = ""; p...[no_index]; // expected-error {{value of type 'const char *' is not implicitly convertible}} } void invalid_index_types() { [] { T...[non_constant_index()] a; // expected-error {{array size is not a constant expression}}\ // expected-note {{cannot be used in a constant expression}} }(); //expected-note {{in instantiation}} } } template constexpr bool is_same = false; template constexpr bool is_same = true; template constexpr bool f(auto&&... p) { return is_same; } void g() { int a = 0; const int b = 0; static_assert(f(0)); static_assert(f(a)); static_assert(f(b)); } template struct check_ice { enum e { x = p...[0] }; }; static_assert(check_ice<42>::x == 42); struct S{}; template constexpr auto constant_initializer = p...[0]; constexpr auto InitOk = constant_initializer; consteval int evaluate(auto... p) { return p...[0]; } constexpr int x = evaluate(42, S{}); static_assert(x == 42); namespace splice { template struct IL{}; template struct TL{}; template struct SpliceImpl; template struct SpliceImpl, IL>{ using type = TL; }; template using Splice = typename SpliceImpl::type; using type = Splice, IL<1, 2>>; static_assert(is_same>); } namespace GH81697 { template struct tuple { int __x0; }; template Ts...[I]& get(tuple& t) { return t.__x0; } void f() { tuple x; get<0>(x); } } namespace GH88929 { bool b = a...[0]; // expected-error {{use of undeclared identifier 'a'}} using E = P...[0]; // expected-error {{unknown type name 'P'}} \ // expected-error {{expected ';' after alias declaration}} } namespace GH88925 { template struct S {}; template struct W {}; template struct sequence {}; template auto f(sequence) { return S(); // #use } template auto g(sequence) { return W(); // #nttp-use } void h() { static_assert(__is_same(decltype(f(sequence<0, 0>())), S)); static_assert(__is_same(decltype(f(sequence<0, 0>())), S)); static_assert(__is_same(decltype(f(sequence<0, 1>())), S)); f(sequence<3>()); // expected-error@#use {{invalid index 3 for pack 'args' of size 2}}} // expected-note-re@-2 {{function template specialization '{{.*}}' requested here}} struct foo {}; struct bar {}; struct baz {}; static_assert(__is_same(decltype(g(sequence<0, 2, 1>())), W)); g(sequence<4>()); // expected-error@#nttp-use {{invalid index 4 for pack 'args' of size 1}} // expected-note-re@-2 {{function template specialization '{{.*}}' requested here}} } } namespace GH91885 { void test(auto...args){ [&](){ using R = decltype( args...[idx] ) ; }.template operator()<0>(); } template void test2(){ [&](){ using R = decltype( args...[idx] ) ; // #test2-R }.template operator()<0>(); // #test2-call } void f( ) { test(1); test2<1>(); test2(); // expected-error@#test2-R {{invalid index 0 for pack 'args' of size 0}} // expected-note@#test2-call {{requested here}} // expected-note@-3 {{requested here}} } } namespace std { struct type_info { const char *name; }; } // namespace std namespace GH93650 { auto func(auto... inputArgs) { return typeid(inputArgs...[0]); } } // namespace GH93650 namespace GH105900 { template struct types { template static constexpr __SIZE_TYPE__ get_index() { return idx; } template static auto x() -> opts...[get_index()] {} }; template struct vars { template static constexpr __SIZE_TYPE__ get_index() { return idx; } template static auto x() -> decltype(opts...[get_index()]) {return 0;} }; void f() { types::x<0>(); vars<0>::x<0>(); } } // namespace GH105900 namespace GH105903 { template struct temp { template static auto x() -> opts... [s] {} // expected-note {{invalid index 0 for pack 'opts' of size 0}} }; void f() { temp<>::x<0>(); // expected-error {{no matching}} } } // namespace GH105903 namespace GH116105 { template using pack_type = Ts...[Np]; template using pack_expr = decltype(Ts...[Np]); template struct types; template struct indices; template struct repack; template struct repack> { template using pack_type_alias = types...>; template using pack_expr_alias = types...>; }; template struct mdispatch_ { using Idx = __make_integer_seq; static_assert(__is_same( typename repack::template pack_type_alias, types)); static_assert(__is_same( typename repack::template pack_expr_alias, types)); }; mdispatch_ d; } // namespace GH116105 namespace GH121242 { // Non-dependent type pack access template int y = x...[0]; struct X {}; template X z = x...[0]; void foo() { (void)y<0>; (void)z; } } // namespace GH121242 namespace GH123033 { template requires __is_same_as(Types...[0], int) void print(double d); template requires __is_same_as(Types...[0], int) void print(double d); template Types...[0] convert(double d); template Types...[0] convert(double d) { return static_cast(d); } void f() { print(12.34); convert(12.34); } }