[gcc r17-2909] c++/reflection: ^^ rejects pack-index-specifier [PR126546]
Marek Polacek via Gcc-cvs <[email protected]> Mon, 3 Aug 2026 21:19:15 +0000 (GMT)
| Newsgroups | gmane.comp.gcc.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://gcc.gnu.org/g:78b03e2296722df3b69f28677cbeed03c1642dbf commit r17-2909-g78b03e2296722df3b69f28677cbeed03c1642dbf Author: Marek Polacek <[email protected]> Date: Mon Aug 3 13:02:01 2026 -0400 c++/reflection: ^^ rejects pack-index-specifier [PR126546] [expr.reflect] says that a reflection of a pack-index-expressions is ill-formed. But that applies to the ^^id-expression production, not ^^type-id, in which a pack-index-specifier (for types) can be used. So it's wrong for get_reflection to check PACK_INDEX_P, it should only reject PACK_INDEX_EXPR. I don't think that currently we can get there with a PACK_INDEX_EXPR though: for a pack-index-expression Xs...[0] cp_parser_reflection_name will consume Xs and then immediately call get_reflection which gives an error. But leaving the PACK_INDEX_EXPR check in doesn't seem like a bad idea. PR c++/126546 gcc/cp/ChangeLog: * reflect.cc (get_reflection): Check PACK_INDEX_EXPR instead of PACK_INDEX_P. gcc/testsuite/ChangeLog: * g++.dg/reflect/pack-index1.C: Accept a reflection of a pack-index-specifier. Reject a reflection of a pack-index-expression. * g++.dg/reflect/pack-index2.C: New test. Reviewed-by: Jason Merrill <[email protected]> Diff: --- gcc/cp/reflect.cc | 2 +- gcc/testsuite/g++.dg/reflect/pack-index1.C | 9 ++++++++- gcc/testsuite/g++.dg/reflect/pack-index2.C | 8 ++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/gcc/cp/reflect.cc b/gcc/cp/reflect.cc index 989d7cebc77c..7b4142f2d4fb 100644 --- a/gcc/cp/reflect.cc +++ b/gcc/cp/reflect.cc @@ -141,7 +141,7 @@ get_reflection (location_t loc, tree t, reflect_kind kind/*=REFLECT_UNDEF*/) /* Constant template parameters and pack-index-expressions cannot appear as operands of the reflection operator. */ - if (PACK_INDEX_P (t)) + if (TREE_CODE (t) == PACK_INDEX_EXPR) { error_at (loc, "%<^^%> cannot be applied to a pack index"); return error_mark_node; diff --git a/gcc/testsuite/g++.dg/reflect/pack-index1.C b/gcc/testsuite/g++.dg/reflect/pack-index1.C index f68705b12991..c2b27a8c133d 100644 --- a/gcc/testsuite/g++.dg/reflect/pack-index1.C +++ b/gcc/testsuite/g++.dg/reflect/pack-index1.C @@ -14,10 +14,16 @@ f () { constexpr auto r1 = ^^Ts...[0]::sx; constexpr auto r2 = ^^typename Ts...[0]::type; + constexpr auto e = ^^Ts...[0]; +} +template<int... Ns> +void +g () +{ // NTTPs and pack-index-expressions cannot appear as operands // of the reflection operator. - constexpr auto e = ^^Ts...[0]; // { dg-error "cannot be applied" } + constexpr auto e = ^^Ns...[0]; // { dg-error "cannot be applied" } } @@ -25,4 +31,5 @@ void g () { f<S>(); + g<1, 2, 3>(); } diff --git a/gcc/testsuite/g++.dg/reflect/pack-index2.C b/gcc/testsuite/g++.dg/reflect/pack-index2.C new file mode 100644 index 000000000000..113629510f11 --- /dev/null +++ b/gcc/testsuite/g++.dg/reflect/pack-index2.C @@ -0,0 +1,8 @@ +// PR c++/126546 +// { dg-do compile { target c++26 } } +// { dg-additional-options "-freflection" } + +template <class... Ts> +consteval auto first() { return ^^Ts...[0]; } + +static_assert(first<int, double>() == ^^int);