[C++ Patch] PR 54575

Paolo Carlini paolo.carlini@oracle.com
Fri Sep 14 13:05:00 GMT 2012


Hi,

here we crash because strip_typedefs while processing _RequireInputIter 
calls make_typename_type which returns error_mark_node (# line 3281). 
Thus I'm simply checking for result == error_mark_node right after the 
switch (in the switch finish_decltype_type could also return 
error_mark_node, for example) and before handling the alignment (where 
we are crashing now). Issue seems rather straightforward.

Tested x86_64-linux.

Thanks,
Paolo.

PS: I'm also attaching a patchlet for a couple of hard errors in 
make_typename_type not protected by (complain & tf_error) spotted in 
make_typename_type.

/////////////////////////
-------------- next part --------------
/cp
2012-09-14  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/54575
	* tree.c (strip_typedefs): Check result for error_mark_node.
	* pt.c (canonicalize_type_argument): Check strip_typedefs return
	value for error_mark_node.

/testsuite
2012-09-14  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/54575
	* g++.dg/cpp0x/pr54575.C: New.
-------------- next part --------------
Index: testsuite/g++.dg/cpp0x/pr54575.C
===================================================================
--- testsuite/g++.dg/cpp0x/pr54575.C	(revision 0)
+++ testsuite/g++.dg/cpp0x/pr54575.C	(revision 0)
@@ -0,0 +1,27 @@
+// PR c++/54575
+// { dg-do compile { target c++11 } }
+
+template<typename _From, typename _To>
+struct is_convertible { static const bool value = true; };
+
+template<bool> struct enable_if       { };
+template<>     struct enable_if<true> { typedef int type; };
+
+template<typename _InIter>
+using _RequireInputIter
+= typename enable_if<is_convertible<_InIter,bool>::value>::type;
+
+template<typename _Tp>
+struct X
+{
+  template<typename _InputIterator,
+	   typename = _RequireInputIter<_InputIterator>>
+    void insert(_InputIterator) {}
+};
+
+template<typename>
+void foo()
+{
+  X<int> subdomain_indices;
+  subdomain_indices.insert(0);
+}
Index: cp/tree.c
===================================================================
--- cp/tree.c	(revision 191290)
+++ cp/tree.c	(working copy)
@@ -1210,8 +1210,10 @@ strip_typedefs (tree t)
       break;
     }
 
+  if (result == error_mark_node)
+    return error_mark_node;
   if (!result)
-      result = TYPE_MAIN_VARIANT (t);
+    result = TYPE_MAIN_VARIANT (t);
   if (TYPE_USER_ALIGN (t) != TYPE_USER_ALIGN (result)
       || TYPE_ALIGN (t) != TYPE_ALIGN (result))
     {
Index: cp/pt.c
===================================================================
--- cp/pt.c	(revision 191290)
+++ cp/pt.c	(working copy)
@@ -6114,6 +6114,8 @@ canonicalize_type_argument (tree arg, tsubst_flags
     return arg;
   mv = TYPE_MAIN_VARIANT (arg);
   arg = strip_typedefs (arg);
+  if (arg == error_mark_node)
+    return error_mark_node;
   if (TYPE_ALIGN (arg) != TYPE_ALIGN (mv)
       || TYPE_ATTRIBUTES (arg) != TYPE_ATTRIBUTES (mv))
     {
-------------- next part --------------
2012-09-14  Paolo Carlini  <paolo.carlini@oracle.com>

	* decl.c (make_typename_type): Only error out if tf_error is set
	in complain.
-------------- next part --------------
Index: decl.c
===================================================================
--- decl.c	(revision 191290)
+++ decl.c	(working copy)
@@ -3235,13 +3235,15 @@ make_typename_type (tree context, tree name, enum
 	name = TREE_OPERAND (fullname, 0) = DECL_NAME (name);
       else if (TREE_CODE (name) == OVERLOAD)
 	{
-	  error ("%qD is not a type", name);
+	  if (complain & tf_error)
+	    error ("%qD is not a type", name);
 	  return error_mark_node;
 	}
     }
   if (TREE_CODE (name) == TEMPLATE_DECL)
     {
-      error ("%qD used without template parameters", name);
+      if (complain & tf_error)
+	error ("%qD used without template parameters", name);
       return error_mark_node;
     }
   gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);


More information about the Gcc-patches mailing list