Hi,

if you like, this ICE is closely related to c++/60848, but occurs when we don't have (yet) a broken definition of std::initializer_list, only a declaration, which is nonetheless able to cause an ICE at the beginning of build_list_conv, as called by implicit_conversion for the testcase at issue.

As such, the broken declaration cannot be rejected by the code we have in finish_struct, something must happen earlier than that. It seems to me that xref_tag_1 can be a good place, per the below patchlet, which passes testing on x86_64-linux. I briefly wondered if making is_std_init_list stricter would make sense instead, but I don't think so (consistently with the trail of c++/60848 too): I believe that by the time we use is_std_init_list in the internals we want something as simple as possible, we are assuming that broken, fake, std::initializer_list aren't around in the translation unit. In terms of details, I also wondered if CLASSTYPE_IS_TEMPLATE would make for a better check, but seems unnecessarily more complex. Also, in principle, we may want to have an even stricter check at declaration time (how many template parameters, etc) but that seems overkilling and I don't think we are risking ICEs because of that.

Thanks, Paolo.

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

Index: cp/decl.c
===================================================================
--- cp/decl.c   (revision 246023)
+++ cp/decl.c   (working copy)
@@ -13645,6 +13645,13 @@ xref_tag_1 (enum tag_types tag_code, tree name,
               in push_template_decl.  */
            CLASSTYPE_LAMBDA_EXPR (t) = error_mark_node;
          t = pushtag (name, t, scope);
+         if (t != error_mark_node
+             && CP_TYPE_CONTEXT (t) == std_node
+             && strcmp (TYPE_NAME_STRING (t), "initializer_list") == 0
+             && !CLASSTYPE_TEMPLATE_INFO (t))
+           fatal_error (input_location,
+                        "declaration of std::initializer_list does not match "
+                        "#include <initializer_list>, isn't a template");
        }
     }
   else
Index: testsuite/g++.dg/cpp0x/initlist97.C
===================================================================
--- testsuite/g++.dg/cpp0x/initlist97.C (revision 0)
+++ testsuite/g++.dg/cpp0x/initlist97.C (working copy)
@@ -0,0 +1,9 @@
+// PR c++/77752
+// { dg-do compile { target c++11 } }
+
+namespace std {
+  class initializer_list;  // { dg-message "initializer_list" }
+}
+void f(std::initializer_list l) { f({2}); }
+
+// { dg-prune-output "compilation terminated" }

Reply via email to