https://gcc.gnu.org/g:afeef7f0d3537cd978931a5afcbd3d91c144bfeb

commit r15-5955-gafeef7f0d3537cd978931a5afcbd3d91c144bfeb
Author: Marek Polacek <pola...@redhat.com>
Date:   Wed Dec 4 16:58:59 2024 -0500

    c++: ICE with pack indexing empty pack [PR117898]
    
    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 tsubst_pack_index, even before we substitute
    the index.  Other erroneous cases can wait until pack_index_element
    where we have the index.
    
            PR c++/117898
    
    gcc/cp/ChangeLog:
    
            * pt.cc (tsubst_pack_index): Detect indexing an empty pack.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/cpp26/pack-indexing2.C: Adjust.
            * g++.dg/cpp26/pack-indexing12.C: New test.

Diff:
---
 gcc/cp/pt.cc                                 |  6 ++++++
 gcc/testsuite/g++.dg/cpp26/pack-indexing12.C | 16 ++++++++++++++++
 gcc/testsuite/g++.dg/cpp26/pack-indexing2.C  | 26 ++++++++++++++++++++------
 3 files changed, 42 insertions(+), 6 deletions(-)

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 1f0f02603288..b094d141f3b0 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -13984,6 +13984,12 @@ tsubst_pack_index (tree t, tree args, tsubst_flags_t 
complain, tree in_decl)
   tree pack = PACK_INDEX_PACK (t);
   if (PACK_EXPANSION_P (pack))
     pack = tsubst_pack_expansion (pack, args, complain, in_decl);
+  if (TREE_CODE (pack) == TREE_VEC && TREE_VEC_LENGTH (pack) == 0)
+    {
+      if (complain & tf_error)
+       error ("cannot index an empty pack");
+      return error_mark_node;
+    }
   tree index = tsubst_expr (PACK_INDEX_INDEX (t), args, complain, in_decl);
   const bool parenthesized_p = (TREE_CODE (t) == PACK_INDEX_EXPR
                                && PACK_INDEX_PARENTHESIZED_P (t));
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 000000000000..d958af3620d0
--- /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
+}
diff --git a/gcc/testsuite/g++.dg/cpp26/pack-indexing2.C 
b/gcc/testsuite/g++.dg/cpp26/pack-indexing2.C
index ec32527ed80f..fdc8320e2555 100644
--- a/gcc/testsuite/g++.dg/cpp26/pack-indexing2.C
+++ b/gcc/testsuite/g++.dg/cpp26/pack-indexing2.C
@@ -42,7 +42,7 @@ template<int N>
 int
 getT (auto... Ts)
 {
-  return Ts...[N]; // { dg-error "pack index is out of range" }
+  return Ts...[N]; // { dg-error "cannot index an empty pack" }
 }
 
 template<int N>
@@ -56,12 +56,26 @@ template<auto N, typename... Ts>
 void
 badtype ()
 {
-  Ts...[N] t; // { dg-error "pack index is out of range" }
+  Ts...[N] t; // { dg-error "cannot index an empty pack" }
 }
 
 template<auto N, typename... Ts>
 void
 badtype2 ()
+{
+  Ts...[N] t; // { dg-error "pack index is out of range" }
+}
+
+template<auto N, typename... Ts>
+void
+badtype3 ()
+{
+  Ts...[N] t; // { dg-error "cannot index an empty pack" }
+}
+
+template<auto N, typename... Ts>
+void
+badtype4 ()
 {
   Ts...[N] t; // { dg-error "pack index is negative" }
 }
@@ -97,12 +111,12 @@ int main()
 
   getT<0>(); // { dg-message "required from here" }
   getT<1>();  // { dg-message "required from here" }
-  getT2<-1>();  // { dg-message "required from here" }
+  getT2<-1>(1);  // { dg-message "required from here" }
 
   badtype<0>(); // { dg-message "required from here" }
-  badtype<1, int>(); // { dg-message "required from here" }
-  badtype2<-1>(); // { dg-message "required from here" }
-  badtype2<-1, int>(); // { dg-message "required from here" }
+  badtype2<1, int>(); // { dg-message "required from here" }
+  badtype3<-1>(); // { dg-message "required from here" }
+  badtype4<-1, int>(); // { dg-message "required from here" }
 
   badindex<int, int, int>();

Reply via email to