In this testcase, we tried to deduce template arguments between __integer_pack(sizeof...(_Types)) and an empty argument list. This breaks, and we shouldn't try anyway, since that's very much a non-deduced context. So let's skip over packs that aren't actual template parameter packs.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit f5e979b7434f372028215a9209f4b8076fab97d7 Author: Jason Merrill <ja...@redhat.com> Date: Sat Mar 24 07:45:02 2018 -0400 PR c++/85049 - ICE with __integer_pack. * pt.c (unify_pack_expansion): Don't try to deduce generated packs. * cp-tree.h (TEMPLATE_PARM_P): New. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index c8f4bc43fa3..db79338035d 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4554,6 +4554,12 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter) || TREE_CODE (NODE) == TYPE_DECL \ || TREE_CODE (NODE) == TEMPLATE_DECL)) +/* Nonzero for a raw template parameter node. */ +#define TEMPLATE_PARM_P(NODE) \ + (TREE_CODE (NODE) == TEMPLATE_TYPE_PARM \ + || TREE_CODE (NODE) == TEMPLATE_TEMPLATE_PARM \ + || TREE_CODE (NODE) == TEMPLATE_PARM_INDEX) + /* Mark NODE as a template parameter. */ #define SET_DECL_TEMPLATE_PARM_P(NODE) \ (DECL_LANG_FLAG_0 (NODE) = 1) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 9cf03f45e24..d6cce3e67da 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -20645,6 +20645,11 @@ unify_pack_expansion (tree tparms, tree targs, tree packed_parms, tree parm_pack = TREE_VALUE (pack); int idx, level; + /* Only template parameter packs can be deduced, not e.g. function + parameter packs or __bases or __integer_pack. */ + if (!TEMPLATE_PARM_P (parm_pack)) + continue; + /* Determine the index and level of this parameter pack. */ template_parm_level_and_index (parm_pack, &level, &idx); if (level < levels) diff --git a/gcc/testsuite/g++.dg/ext/integer-pack3.C b/gcc/testsuite/g++.dg/ext/integer-pack3.C new file mode 100644 index 00000000000..d3ed1363016 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/integer-pack3.C @@ -0,0 +1,21 @@ +// PR c++/85049 +// { dg-do compile { target c++11 } } + +typedef __SIZE_TYPE__ size_t; +template<typename _Tp, _Tp... _Idx> +struct integer_sequence +{ + typedef _Tp value_type; + static constexpr size_t size() noexcept { return sizeof...(_Idx); } +}; +template<typename _Tp, _Tp _Num> +using make_integer_sequence = integer_sequence<_Tp, __integer_pack(_Num)...>; +template<size_t _Num> +using make_index_sequence = make_integer_sequence<size_t, _Num>; +template<typename... _Types> +using index_sequence_for = make_index_sequence<sizeof...(_Types)>; +template <typename...> +struct tuple {}; +template <typename... Ts> +int get(tuple<index_sequence_for<Ts...>, Ts...>); +int x = get(tuple<index_sequence_for<>>{});