return result;
}
+/* Substitute ARGS into T, which is a TREE_VEC. This function creates a new
+ TREE_VEC rather than substituting the elements in-place. */
+
+static tree
+tsubst_tree_vec (tree t, tree args, tsubst_flags_t complain, tree in_decl)
+{
+ const int len = TREE_VEC_LENGTH (t);
+ tree r = make_tree_vec (len);
+ for (int i = 0; i < len; ++i)
+ {
+ tree arg = TREE_VEC_ELT (t, i);
+ if (TYPE_P (arg))
+ TREE_VEC_ELT (r, i) = tsubst (arg, args, complain, in_decl);
+ else
+ TREE_VEC_ELT (r, i) = tsubst_expr (arg, args, complain, in_decl);
+ }
+ return r;
+}
+
/* Substitute ARGS into T, which is a pack index (i.e., PACK_INDEX_TYPE or
PACK_INDEX_EXPR). Returns a single type or expression, a PACK_INDEX_*
node if only a partial substitution could be performed, or ERROR_MARK_NODE
a partially instantiated closure. Let tsubst find the
fully-instantiated one. */
gcc_assert (TREE_CODE (pack) == TREE_VEC);
- pack = tsubst (pack, args, complain, in_decl);
+ pack = tsubst_tree_vec (pack, args, complain, in_decl);
}
if (TREE_CODE (pack) == TREE_VEC && TREE_VEC_LENGTH (pack) == 0)
{
--- /dev/null
+// 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>)));
+}