Here we have a non-dependent constructor in a template: { VIEW_CONVERT_EXPR<const A>(j) }
In digest_init we call massage_init_elt, which calls digest_init_r on the element. We convert the element, but we're in a template, so perform_implicit_conversion added an IMPLICIT_CONV_EXPR around it. And then massage_init_elt calls maybe_constant_init on the element and the usual sadness ensues. Fixed as below, so that we don't introduce additional template codes in the middle of converting the element. Bootstrapped/regtested on x86_64-linux, ok for trunk? 2019-03-27 Marek Polacek <pola...@redhat.com> PR c++/89852 - ICE with C++11 functional cast with { }. * semantics.c (finish_compound_literal): Clear processing_template_decl. * g++.dg/cpp0x/initlist115.C: New test. diff --git gcc/cp/semantics.c gcc/cp/semantics.c index a08a2a57f5f..4bbd506d96f 100644 --- gcc/cp/semantics.c +++ gcc/cp/semantics.c @@ -2872,6 +2872,11 @@ finish_compound_literal (tree type, tree compound_literal, if (type == error_mark_node) return error_mark_node; } + + /* Here the constructor is non-dependent, so perform any conversions in + non-dependent context as well. */ + processing_template_decl_sentinel s; + compound_literal = digest_init_flags (type, compound_literal, LOOKUP_NORMAL | LOOKUP_NO_NARROWING, complain); diff --git gcc/testsuite/g++.dg/cpp0x/initlist115.C gcc/testsuite/g++.dg/cpp0x/initlist115.C new file mode 100644 index 00000000000..ee4b6d4a870 --- /dev/null +++ gcc/testsuite/g++.dg/cpp0x/initlist115.C @@ -0,0 +1,18 @@ +// PR c++/89852 +// { dg-do compile { target c++11 } } + +struct A { + int b; +}; + +struct B { + A g; +}; + +const auto j = A{}; + +template <typename> +void k() +{ + B{j}; +}