Hi,

the main issue is already fixed in trunk but we still ICE on the reduced testcase attached by Jakub which has a broken std::initializer_list missing the definition. I think we can handle this case similarly to the existing check in do_pushtag, which would be also consistent with the plain error we give for, eg:

namespace std { template <class> class initializer_list; }

template class std::initializer_list<int>;

However, we still have the option of issuing a fatal_error, like we do in finish_struct.

In any case, I'm tweaking for consistency do_pushtag about %< and %>.

Tested x86_64-linux.

Thanks, Paolo.

///////////////////

/cp
2018-04-05  Paolo Carlini  <paolo.carl...@oracle.com>

        PR c++/80956
        * call.c (convert_like_real): Fail gracefully for a broken
        std::initializer_list, missing a definition.

        * name-lookup.c (do_pushtag): Tweak message, use %< and %>.

/testsuite
2018-04-05  Paolo Carlini  <paolo.carl...@oracle.com>

        PR c++/80956
        * g++.dg/cpp0x/initlist100.C: New.
        * g++.dg/cpp0x/initlist101.C: Likewise.
Index: cp/call.c
===================================================================
--- cp/call.c   (revision 259124)
+++ cp/call.c   (working copy)
@@ -6880,8 +6880,19 @@ convert_like_real (conversion *convs, tree expr, t
        if (array == error_mark_node)
          return error_mark_node;
 
-       /* Build up the initializer_list object.  */
+       /* Build up the initializer_list object.  Note: fail gracefully
+          if the object cannot be completed because, for example, no
+          definition is provided.  */
        totype = complete_type (totype);
+       if (!COMPLETE_TYPE_P (totype))
+         {
+           if (complain & tf_error)
+             error_at (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (totype)),
+                       "declaration of %<std::initializer_list%> does not "
+                       "match %<#include <initializer_list>%>, cannot be "
+                       "completed");
+           return error_mark_node;
+         }
        field = next_initializable_field (TYPE_FIELDS (totype));
        CONSTRUCTOR_APPEND_ELT (vec, field, array);
        field = next_initializable_field (DECL_CHAIN (field));
Index: cp/name-lookup.c
===================================================================
--- cp/name-lookup.c    (revision 259124)
+++ cp/name-lookup.c    (working copy)
@@ -6476,8 +6476,8 @@ do_pushtag (tree name, tree type, tag_scope scope)
              && init_list_identifier == DECL_NAME (TYPE_NAME (type))
              && !CLASSTYPE_TEMPLATE_INFO (type))
            {
-             error ("declaration of std::initializer_list does not match "
-                    "#include <initializer_list>, isn't a template");
+             error ("declaration of %<std::initializer_list%> does not match "
+                    "%<#include <initializer_list>%>, isn't a template");
              return error_mark_node;
            }
        }
Index: testsuite/g++.dg/cpp0x/initlist100.C
===================================================================
--- testsuite/g++.dg/cpp0x/initlist100.C        (nonexistent)
+++ testsuite/g++.dg/cpp0x/initlist100.C        (working copy)
@@ -0,0 +1,10 @@
+// PR c++/80956
+// { dg-do compile { target c++11 } }
+
+namespace std {
+template <class> class initializer_list;  // { dg-error "declaration of 
.*std::initializer_list.* does not match" }
+}
+
+template <typename T> struct B { B (std::initializer_list<T>); };
+struct C { virtual int foo (); };
+struct D : C {} d { B<C> { D {} } };  // { dg-error "no matching" }
Index: testsuite/g++.dg/cpp0x/initlist101.C
===================================================================
--- testsuite/g++.dg/cpp0x/initlist101.C        (nonexistent)
+++ testsuite/g++.dg/cpp0x/initlist101.C        (working copy)
@@ -0,0 +1,8 @@
+// PR c++/80956
+// { dg-do compile { target c++11 } }
+
+#include <initializer_list>
+
+template <typename T> struct B { B (std::initializer_list<T>); };
+struct C { virtual int foo (); };
+struct D : C {} d { B<C> { D {} } };  // { dg-error "no matching" }

Reply via email to