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
> 
> 

Reply via email to