While looking at the other PR I came across this ICE. We're substituting {.a={[0 ... 3]=0}}
which contains a RANGE_EXPR that build_value_init_noctor created, but none of the tsubst_* functions handle it. As discussed in the PR, a RANGE_EXPR will always be created with constant operands, so there's no need to recurse further. Bootstrapped/regtest running on x86_64-linux, ok for trunk and 8/7? 2019-01-30 Marek Polacek <pola...@redhat.com> PR c++/89119 - ICE with value-initialization in template. * pt.c (tsubst_copy_and_build): Handle RANGE_EXPR. * g++.dg/cpp0x/initlist-value3.C: New test. diff --git gcc/cp/pt.c gcc/cp/pt.c index cb06a570d48..f92fa1a1813 100644 --- gcc/cp/pt.c +++ gcc/cp/pt.c @@ -19412,6 +19412,11 @@ tsubst_copy_and_build (tree t, case REQUIRES_EXPR: RETURN (tsubst_requires_expr (t, args, complain, in_decl)); + case RANGE_EXPR: + /* No need to substitute further, a RANGE_EXPR will always be built + with constant operands. */ + RETURN (t); + case NON_LVALUE_EXPR: case VIEW_CONVERT_EXPR: if (location_wrapper_p (t)) diff --git gcc/testsuite/g++.dg/cpp0x/initlist-value3.C gcc/testsuite/g++.dg/cpp0x/initlist-value3.C new file mode 100644 index 00000000000..03db25d1652 --- /dev/null +++ gcc/testsuite/g++.dg/cpp0x/initlist-value3.C @@ -0,0 +1,23 @@ +// PR c++/89119 +// { dg-do compile { target c++11 } } + +struct S { int a[4]; }; + +template<int N> +struct R { int a[N]; }; + +template <typename T> +void +fn () +{ + constexpr auto s = S(); + constexpr auto s2 = S{}; + constexpr auto r = R<4>(); + constexpr auto r2 = R<4>{}; +} + +void +foo () +{ + fn<int>(); +}