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};
+}

Reply via email to