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 <[email protected]>
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};
+}