From d849cfaeeaf15a30170b0fb10b4f62075a1ee58b Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 18 Mar 2019 15:35:12 -0400 Subject: [PATCH] PR c++/89761 - ICE with sizeof... in pack expansion. In this testcase we get confused when looking at the sizeof... because the argument pack for 'args' has been wrapped in an ARGUMENT_PACK_SELECT as part of expanding the fold-expression. We handle this situation a bit lower down in tsubst_pack_expansion, but that doesn't help the call to argument_pack_element_is_expansion_p, which happens earlier. * pt.c (argument_pack_element_is_expansion_p): Handle ARGUMENT_PACK_SELECT. From-SVN: r269776 --- gcc/cp/ChangeLog | 4 ++++ gcc/cp/pt.c | 3 +++ gcc/testsuite/g++.dg/cpp1z/fold10.C | 17 +++++++++++++++++ 3 files changed, 24 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp1z/fold10.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a3341bd9672..d4dc5d7146a 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2019-03-18 Jason Merrill + PR c++/89761 - ICE with sizeof... in pack expansion. + * pt.c (argument_pack_element_is_expansion_p): Handle + ARGUMENT_PACK_SELECT. + PR c++/89640 - GNU attributes on lambda. * parser.c (cp_parser_lambda_declarator_opt): Allow GNU attributes. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 7dc6e44cf7b..0acc16d1b92 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -11544,6 +11544,9 @@ make_fnparm_pack (tree spec_parm) static int argument_pack_element_is_expansion_p (tree arg_pack, int i) { + if (TREE_CODE (arg_pack) == ARGUMENT_PACK_SELECT) + /* We're being called before this happens in tsubst_pack_expansion. */ + arg_pack = ARGUMENT_PACK_SELECT_FROM_PACK (arg_pack); tree vec = ARGUMENT_PACK_ARGS (arg_pack); if (i >= TREE_VEC_LENGTH (vec)) return 0; diff --git a/gcc/testsuite/g++.dg/cpp1z/fold10.C b/gcc/testsuite/g++.dg/cpp1z/fold10.C new file mode 100644 index 00000000000..1bd39a05400 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/fold10.C @@ -0,0 +1,17 @@ +// PR c++/89761 +// { dg-do compile { target c++17 } } + +template struct seq {}; +template struct S { + template + constexpr static void call(Args&&...) {} +}; + +template +auto foo (seq, Args&& ...args) { + return (S::call(args), ...); +} + +void bar() { + foo(seq<0,1,2>{}, 1,2,3); +} -- 2.30.2