aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2024-12-04 16:58:59 -0500
committerMarek Polacek <polacek@redhat.com>2024-12-05 20:12:02 -0500
commitafeef7f0d3537cd978931a5afcbd3d91c144bfeb (patch)
treedcafb1e30d048679d9ce1cc193be1cc701a706f5 /gcc
parent3ac3093756cd00f50e63e8dcde4d278606722105 (diff)
downloadgcc-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.cc6
-rw-r--r--gcc/testsuite/g++.dg/cpp26/pack-indexing12.C16
-rw-r--r--gcc/testsuite/g++.dg/cpp26/pack-indexing2.C26
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>();