Skip to content

Commit afeef7f

Browse files
committed
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.
1 parent 3ac3093 commit afeef7f

File tree

3 files changed

+42
-6
lines changed

3 files changed

+42
-6
lines changed

gcc/cp/pt.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13984,6 +13984,12 @@ tsubst_pack_index (tree t, tree args, tsubst_flags_t complain, tree in_decl)
1398413984
tree pack = PACK_INDEX_PACK (t);
1398513985
if (PACK_EXPANSION_P (pack))
1398613986
pack = tsubst_pack_expansion (pack, args, complain, in_decl);
13987+
if (TREE_CODE (pack) == TREE_VEC && TREE_VEC_LENGTH (pack) == 0)
13988+
{
13989+
if (complain & tf_error)
13990+
error ("cannot index an empty pack");
13991+
return error_mark_node;
13992+
}
1398713993
tree index = tsubst_expr (PACK_INDEX_INDEX (t), args, complain, in_decl);
1398813994
const bool parenthesized_p = (TREE_CODE (t) == PACK_INDEX_EXPR
1398913995
&& PACK_INDEX_PARENTHESIZED_P (t));
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// PR c++/117898
2+
// { dg-do compile { target c++26 } }
3+
4+
void
5+
ICE (auto... args)
6+
{
7+
[&]<int idx>() {
8+
using R = decltype(args...[idx]); // { dg-error "cannot index an empty pack" }
9+
}.template operator()<0>();
10+
}
11+
12+
void
13+
g ()
14+
{
15+
ICE(); // empty pack
16+
}

gcc/testsuite/g++.dg/cpp26/pack-indexing2.C

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ template<int N>
4242
int
4343
getT (auto... Ts)
4444
{
45-
return Ts...[N]; // { dg-error "pack index is out of range" }
45+
return Ts...[N]; // { dg-error "cannot index an empty pack" }
4646
}
4747

4848
template<int N>
@@ -56,12 +56,26 @@ template<auto N, typename... Ts>
5656
void
5757
badtype ()
5858
{
59-
Ts...[N] t; // { dg-error "pack index is out of range" }
59+
Ts...[N] t; // { dg-error "cannot index an empty pack" }
6060
}
6161

6262
template<auto N, typename... Ts>
6363
void
6464
badtype2 ()
65+
{
66+
Ts...[N] t; // { dg-error "pack index is out of range" }
67+
}
68+
69+
template<auto N, typename... Ts>
70+
void
71+
badtype3 ()
72+
{
73+
Ts...[N] t; // { dg-error "cannot index an empty pack" }
74+
}
75+
76+
template<auto N, typename... Ts>
77+
void
78+
badtype4 ()
6579
{
6680
Ts...[N] t; // { dg-error "pack index is negative" }
6781
}
@@ -97,12 +111,12 @@ int main()
97111

98112
getT<0>(); // { dg-message "required from here" }
99113
getT<1>(); // { dg-message "required from here" }
100-
getT2<-1>(); // { dg-message "required from here" }
114+
getT2<-1>(1); // { dg-message "required from here" }
101115

102116
badtype<0>(); // { dg-message "required from here" }
103-
badtype<1, int>(); // { dg-message "required from here" }
104-
badtype2<-1>(); // { dg-message "required from here" }
105-
badtype2<-1, int>(); // { dg-message "required from here" }
117+
badtype2<1, int>(); // { dg-message "required from here" }
118+
badtype3<-1>(); // { dg-message "required from here" }
119+
badtype4<-1, int>(); // { dg-message "required from here" }
106120

107121
badindex<int, int, int>();
108122

0 commit comments

Comments
 (0)