On Wed, 4 Feb 2026, Patrick Palka wrote:
> On Wed, 4 Feb 2026, Marek Polacek wrote:
>
> > On Wed, Feb 04, 2026 at 10:38:42AM -0500, Patrick Palka wrote:
> > > Bootstrap and regtest running on x86_64-pc-linux-gnu, does this look
> > > OK for trunk/15?
> > >
> > > -- >8 --
> > >
> > > Since type pack indexes can be cv-qualified, we need to propagate its
> > > qualifiers when substituting into them.
> > >
> > > PR c++/122169
> > >
> > > gcc/cp/ChangeLog:
> > >
> > > * pt.cc (tsubst_pack_index): Propagate cv-qualifiers of a
> > > PACK_INDEX_TYPE.
> > >
> > > gcc/testsuite/ChangeLog:
> > >
> > > * g++.dg/cpp26/pack-indexing19.C: New test.
> > > ---
> > > gcc/cp/pt.cc | 9 +++++++--
> > > gcc/testsuite/g++.dg/cpp26/pack-indexing19.C | 18 ++++++++++++++++++
> > > 2 files changed, 25 insertions(+), 2 deletions(-)
> > > create mode 100644 gcc/testsuite/g++.dg/cpp26/pack-indexing19.C
> > >
> > > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
> > > index b8039b731b63..f43bf2ef2d50 100644
> > > --- a/gcc/cp/pt.cc
> > > +++ b/gcc/cp/pt.cc
> > > @@ -14366,10 +14366,15 @@ tsubst_pack_index (tree t, tree args,
> > > tsubst_flags_t complain, tree in_decl)
> > > 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));
> > > + tree r;
> > > if (!value_dependent_expression_p (index) && TREE_CODE (pack) ==
> > > TREE_VEC)
> > > - return pack_index_element (index, pack, parenthesized_p, complain);
> > > + r = pack_index_element (index, pack, parenthesized_p, complain);
> > > else
> > > - return make_pack_index (pack, index);
> > > + r = make_pack_index (pack, index);
> > > + if (TREE_CODE (t) == PACK_INDEX_TYPE)
> >
> > No need to check that r is a type, I suppose, since cp_build_qualified_type
> > can deal with an error_mark_node and it can't be anything else than a type.
>
> That was my thinking too.
>
> >
> > > + r = cp_build_qualified_type (r, cp_type_quals (t) | cp_type_quals
> > > (r),
> >
> > Won't cp_type_quals (r) always be TYPE_UNQUALIFIED?
>
> Yes if it's a PACK_INDEX_TYPE, but if we fully resolve the pack index
> then r could be arbitrary and cv-qualified, e.g. if in the testcase we
> instantiate f<volatile int>().
>
I'm going to extend the testcase to verify cv-quals are merged, not just
propagated:
diff --git a/gcc/testsuite/g++.dg/cpp26/pack-indexing19.C
b/gcc/testsuite/g++.dg/cpp26/pack-indexing19.C
index 7028a232a9cf..b15cd8d2ff31 100644
--- a/gcc/testsuite/g++.dg/cpp26/pack-indexing19.C
+++ b/gcc/testsuite/g++.dg/cpp26/pack-indexing19.C
@@ -16,16 +16,3 @@ void f() {
}
template void f<int>();
+
+template<class... Ts>
+void g() {
+ using T = Ts...[0];
+ static_assert(same_as<const T, const volatile int>);
+
+ []<int I>() {
+ using U = Ts...[I];
+ static_assert(same_as<const U, const volatile int>);
+ }.template operator()<0>();
+}
+
+template void g<volatile int>();
Thanks for the review!
> >
> > Patch LGTM otherwise, thanks!
> >
> > Marek
> >
> >
>