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