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