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.

/////////////////////////
/cp
2012-09-14  Paolo Carlini  <paolo.carl...@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.carl...@oracle.com>

        PR c++/54575
        * g++.dg/cpp0x/pr54575.C: New.
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))
     {
2012-09-14  Paolo Carlini  <paolo.carl...@oracle.com>

        * decl.c (make_typename_type): Only error out if tf_error is set
        in complain.
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);

Reply via email to