Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/15?

-- >8 --
In my r15-6792 patch I added a call to tsubst in tsubst_pack_index
to fully instantiate args#N in the pack.

Here we are in an unevaluated context, but since the pack is
a TREE_VEC, we call tsubst_template_args which has cp_evaluated
at the beginning.  That causes a crash because we trip on the
assert in tsubst_expr/PARM_DECL:

  gcc_assert (cp_unevaluated_operand);

because retrieve_local_specialization didn't find anything (becase
there are no local_specializations yet).

ISTM that we don't need a full instantiation in an unevaluated context
so we can avoid the crash like this.

        PR c++/121325

gcc/cp/ChangeLog:

        * pt.cc (tsubst_pack_index): Don't call tsubst in an unevaluated
        context.

gcc/testsuite/ChangeLog:

        * g++.dg/cpp26/pack-indexing18.C: New test.
---
 gcc/cp/pt.cc                                 |  7 +++--
 gcc/testsuite/g++.dg/cpp26/pack-indexing18.C | 32 ++++++++++++++++++++
 2 files changed, 37 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp26/pack-indexing18.C

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index c418edc6931..1e3cb6ac32d 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -14215,11 +14215,14 @@ 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);
-  else
+  else if (!cp_unevaluated_operand)
     {
       /* PACK can be {*args#0} whose args#0's value-expr refers to
         a partially instantiated closure.  Let tsubst find the
-        fully-instantiated one.  */
+        fully-instantiated one.  In an unevaluated context we don't
+        call this because tsubst_template_args switches back to
+        evaluated context immediately, and we may have parameters
+        without local specializations.  */
       gcc_assert (TREE_CODE (pack) == TREE_VEC);
       pack = tsubst (pack, args, complain, in_decl);
     }
diff --git a/gcc/testsuite/g++.dg/cpp26/pack-indexing18.C 
b/gcc/testsuite/g++.dg/cpp26/pack-indexing18.C
new file mode 100644
index 00000000000..d3e3730408c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp26/pack-indexing18.C
@@ -0,0 +1,32 @@
+// PR c++/121325
+// { dg-do compile { target c++26 } }
+
+void f(auto... a) requires requires { []<int i = 0> 
noexcept(noexcept(a...[i])) { }(); } {}
+void g(auto... a) requires requires { []<int i = 0> { 
static_assert(noexcept(a...[i])); }(); } {}
+
+void
+h ()
+{
+  f (0);
+  g (0);
+}
+
+void foo () {}
+void bar () noexcept {}
+template<bool B>
+void baz () noexcept(B) {}
+
+template<typename... Ts>
+void
+x (Ts... ts) noexcept (noexcept (ts...[0]()))
+{
+}
+
+void
+y ()
+{
+  static_assert (!noexcept (x (foo)));
+  static_assert (noexcept (x (bar)));
+  static_assert (noexcept (x (baz<true>)));
+  static_assert (!noexcept (x (baz<false>)));
+}

base-commit: a2f4b0466be29c853c32498ae49c1acfa1594f30
-- 
2.51.1

Reply via email to