[C++ Patch/RFC] PR 77752

Paolo Carlini paolo.carlini@oracle.com
Fri Mar 10 14:59:00 GMT 2017


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.

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

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


More information about the Gcc-patches mailing list