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" }