On Thu, Dec 05, 2024 at 09:29:41AM -0500, Patrick Palka wrote:
> 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.

I think I agree.  I think I wanted to stay around that TREE_VEC
assert in make_pack_index, but with the patch below I don't have
to bother with the complain parameter and I can also bail sooner,
before substituting the index.

Thanks,

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 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.
---
 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(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp26/pack-indexing12.C

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 1f0f0260328..b094d141f3b 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 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
+}
diff --git a/gcc/testsuite/g++.dg/cpp26/pack-indexing2.C 
b/gcc/testsuite/g++.dg/cpp26/pack-indexing2.C
index ec32527ed80..fdc8320e255 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>();
 

base-commit: b3cb0c3302a7c16e661a08c15c897c8f7bbb5d23
-- 
2.47.1

Reply via email to