[C++ Patch] PR 80956 ("[7/8 Regression] ICE with abstract class vector")

Paolo Carlini paolo.carlini@oracle.com
Thu Apr 5 14:07:00 GMT 2018


Hi,

On 05/04/2018 15:56, Jason Merrill wrote:
> On Thu, Apr 5, 2018 at 8:27 AM, Paolo Carlini <paolo.carlini@oracle.com> wrote:
>> 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.
> How about using complete_type_or_maybe_complain instead of a custom error?
Yes, I was about to send a message about that option, I already had it 
in the audit trail, tested too, then started fiddling with fatal_errors 
and forgot to mention it ;) Anyway, would be the below.

Thanks,
Paolo.

/////////////////////
-------------- next part --------------
Index: cp/call.c
===================================================================
--- cp/call.c	(revision 259124)
+++ cp/call.c	(working copy)
@@ -6880,8 +6880,12 @@ convert_like_real (conversion *convs, tree expr, t
 	if (array == error_mark_node)
 	  return error_mark_node;
 
-	/* Build up the initializer_list object.  */
-	totype = complete_type (totype);
+	/* 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_or_maybe_complain (totype, NULL_TREE, complain);
+	if (!totype)
+	  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-message "declaration" }
+}
+
+template <typename T> struct B { B (std::initializer_list<T>); };
+struct C { virtual int foo (); };
+struct D : C {} d { B<C> { D {} } };  // { dg-error "incomplete|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" }


More information about the Gcc-patches mailing list