diff options
author | Marek Polacek <polacek@redhat.com> | 2024-12-04 16:58:59 -0500 |
---|---|---|
committer | Marek Polacek <polacek@redhat.com> | 2024-12-05 20:12:02 -0500 |
commit | afeef7f0d3537cd978931a5afcbd3d91c144bfeb (patch) | |
tree | dcafb1e30d048679d9ce1cc193be1cc701a706f5 /gcc | |
parent | 3ac3093756cd00f50e63e8dcde4d278606722105 (diff) | |
download | gcc-afeef7f0d3537cd978931a5afcbd3d91c144bfeb.zip gcc-afeef7f0d3537cd978931a5afcbd3d91c144bfeb.tar.gz gcc-afeef7f0d3537cd978931a5afcbd3d91c144bfeb.tar.bz2 |
c++: ICE with pack indexing empty pack [PR117898]
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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/pt.cc | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp26/pack-indexing12.C | 16 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp26/pack-indexing2.C | 26 |
3 files changed, 42 insertions, 6 deletions
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 1f0f026..b094d14 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 0000000..d958af3 --- /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 ec32527..fdc8320 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,13 +56,27 @@ 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>(); |