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);