On Wed, 4 Dec 2024, Marek Polacek wrote: > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? > > -- >8 -- > Here we ICE with a partially-substituted pack indexing. The pack > expanded to an empty pack, which we can't index.
IIUC this can only happen when called from tsubst_pack_index right? In that case maybe we should directly diagnose the error there. That way we make_pack_index remains nice and simple. > It seems reasonable > to detect this case in make_pack_index. Other erroneous cases can > wait until pack_index_element where we have the index. > > PR c++/117898 > > gcc/cp/ChangeLog: > > * cp-tree.h (make_pack_index): Add a complain parameter with a > default argument. > * pt.cc (make_pack_index): Detect indexing an empty pack. > (tsubst_pack_index): Pass COMPLAIN down to make_pack_index. > > gcc/testsuite/ChangeLog: > > * g++.dg/cpp26/pack-indexing12.C: New test. > --- > gcc/cp/cp-tree.h | 3 ++- > gcc/cp/pt.cc | 14 +++++++++++--- > gcc/testsuite/g++.dg/cpp26/pack-indexing12.C | 16 ++++++++++++++++ > 3 files changed, 29 insertions(+), 4 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/cpp26/pack-indexing12.C > > diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h > index 29f28d5e383..8be4aafff8f 100644 > --- a/gcc/cp/cp-tree.h > +++ b/gcc/cp/cp-tree.h > @@ -7602,7 +7602,8 @@ extern bool template_parameter_pack_p > (const_tree); > extern bool function_parameter_pack_p (const_tree); > extern bool function_parameter_expanded_from_pack_p (tree, tree); > extern tree make_pack_expansion (tree, tsubst_flags_t = > tf_warning_or_error); > -extern tree make_pack_index (tree, tree); > +extern tree make_pack_index (tree, tree, > + tsubst_flags_t = > tf_warning_or_error); > extern bool check_for_bare_parameter_packs (tree, location_t = > UNKNOWN_LOCATION); > extern tree build_template_info (tree, tree); > extern tree get_template_info (const_tree); > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc > index 182f18d0e24..242ad0d2012 100644 > --- a/gcc/cp/pt.cc > +++ b/gcc/cp/pt.cc > @@ -4273,7 +4273,8 @@ make_pack_expansion (tree arg, tsubst_flags_t complain) > /* Create a PACK_INDEX_* using the pack expansion PACK and index INDEX. */ > > tree > -make_pack_index (tree pack, tree index) > +make_pack_index (tree pack, tree index, > + tsubst_flags_t complain/*=tf_warning_or_error*/) > { > if (pack == error_mark_node) > return error_mark_node; > @@ -4287,7 +4288,14 @@ make_pack_index (tree pack, tree index) > { > /* Maybe we've already partially substituted the pack. */ > gcc_checking_assert (TREE_CODE (pack) == TREE_VEC); > - for_types = TYPE_P (TREE_VEC_ELT (pack, 0)); > + if (TREE_VEC_LENGTH (pack) == 0) > + { > + if (complain & tf_error) > + error ("cannot index an empty pack"); > + return error_mark_node; > + } > + else > + for_types = TYPE_P (TREE_VEC_ELT (pack, 0)); > } > > tree t = (for_types > @@ -13990,7 +13998,7 @@ tsubst_pack_index (tree t, tree args, tsubst_flags_t > complain, tree in_decl) > if (!value_dependent_expression_p (index) && TREE_CODE (pack) == TREE_VEC) > return pack_index_element (index, pack, parenthesized_p, complain); > else > - return make_pack_index (pack, index); > + return make_pack_index (pack, index, complain); > } > > /* Make an argument pack out of the TREE_VEC VEC. */ > diff --git a/gcc/testsuite/g++.dg/cpp26/pack-indexing12.C > b/gcc/testsuite/g++.dg/cpp26/pack-indexing12.C > new file mode 100644 > index 00000000000..d958af3620d > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp26/pack-indexing12.C > @@ -0,0 +1,16 @@ > +// PR c++/117898 > +// { dg-do compile { target c++26 } } > + > +void > +ICE (auto... args) > +{ > + [&]<int idx>() { > + using R = decltype(args...[idx]); // { dg-error "cannot index an empty > pack" } > + }.template operator()<0>(); > +} > + > +void > +g () > +{ > + ICE(); // empty pack > +} > > base-commit: 68aefc6988dc34d4b9a2194f9fb08bccfe7a076b > -- > 2.47.1 > >