[C++ Patch] PR 60383

Paolo Carlini paolo.carlini@oracle.com
Thu Mar 13 14:06:00 GMT 2014


Hi,

this 4.9 regression is again an ICE during error recovery: 
check_specialization_namespace errors out, 
maybe_process_partial_specialization doesn't check its return value, and 
the ICE happens much later, in retrieve_specialization, in the gcc_assert:

   /* There should be as many levels of arguments as there are
      levels of parameters.  */
   gcc_assert (TMPL_ARGS_DEPTH (args)
           == (TREE_CODE (tmpl) == TEMPLATE_DECL
           ? TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl))
           : template_class_depth (DECL_CONTEXT (tmpl))));

Simply checking the return value of check_specialization_namespace and 
early returning error_mark_node appears to work well, with the minor 
complication that check_specialization_namespace may return false also 
in case of permerror, thus the !at_namespace_scope_p. Other than that, 
the tweak to crash95.C doesn't seem bad to me (for example, it aligns 
our diagnostic to that of current clang)

Tested x86_64-linux.

Thanks,
Paolo.

////////////////////
-------------- next part --------------
/cp
2014-03-13  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/60383
	* pt.c (maybe_process_partial_specialization): Check return value
	of check_specialization_namespace.

/testsuite
2014-03-13  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/60383
	* g++.dg/template/crash118.C: New.
	* g++.dg/template/crash95.C: Adjust.
-------------- next part --------------
Index: cp/pt.c
===================================================================
--- cp/pt.c	(revision 208538)
+++ cp/pt.c	(working copy)
@@ -850,7 +850,9 @@ maybe_process_partial_specialization (tree type)
       if (CLASSTYPE_IMPLICIT_INSTANTIATION (type)
 	  && !COMPLETE_TYPE_P (type))
 	{
-	  check_specialization_namespace (CLASSTYPE_TI_TEMPLATE (type));
+	  if (!check_specialization_namespace (CLASSTYPE_TI_TEMPLATE (type))
+	      && !at_namespace_scope_p ())
+	    return error_mark_node;
 	  SET_CLASSTYPE_TEMPLATE_SPECIALIZATION (type);
 	  DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type)) = input_location;
 	  if (processing_template_decl)
Index: testsuite/g++.dg/template/crash118.C
===================================================================
--- testsuite/g++.dg/template/crash118.C	(revision 0)
+++ testsuite/g++.dg/template/crash118.C	(working copy)
@@ -0,0 +1,11 @@
+// PR c++/60383
+
+template<int> struct A
+{
+  template<typename> struct B
+  {
+    template<typename T> struct B<T*> {};  // { dg-error "specialization" }
+  };
+};
+
+A<0>::B<char*> b;
Index: testsuite/g++.dg/template/crash95.C
===================================================================
--- testsuite/g++.dg/template/crash95.C	(revision 208538)
+++ testsuite/g++.dg/template/crash95.C	(working copy)
@@ -8,4 +8,4 @@ template < typename > struct S
   };
 };
 
-S < int > s(0); // { dg-error "incomplete type" }
+S < int > s(0); // { dg-error "no matching" }


More information about the Gcc-patches mailing list