[C++ Patch] PR 58448
Paolo Carlini
paolo.carlini@oracle.com
Wed Sep 18 00:03:00 GMT 2013
Hi,
this ICE is caused by error_mark_node as TREE_TYPE of a TYPE_DECL, which
leads to a crash at the beginning of the TYPE_DECL case of tsubst_decl.
I tried various approaches - for example turning all error_operand_p (t)
== true arguments passes to tsubst into error_mark_nodes also works -
but I think I have a weak preference for the solution below, because
conceptually matches the section of grokdeclarator beginning with:
/* If this is declaring a typedef name, return a TYPE_DECL. */
if (typedef_p && decl_context != TYPENAME)
which seems rather special in terms of producing such TYPE_DECLs in case
of errors (it does that for error recovery reasons, I suppose: just
returning error_mark_node leads to worse diagnostic for eg,
parse/error32.C).
Tested x86_64-linux.
Thanks,
Paolo.
///////////////////////
-------------- next part --------------
/cp
2013-09-17 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/58448
* pt.c (tsubst_decl, [TYPE_DECL]): Check TREE_TYPE (t) for
error_mark_node.
/testsuite
2013-09-17 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/58448
* g++.dg/template/crash117.C: New.
-------------- next part --------------
Index: cp/pt.c
===================================================================
--- cp/pt.c (revision 202668)
+++ cp/pt.c (working copy)
@@ -10741,19 +10741,23 @@ tsubst_decl (tree t, tree args, tsubst_flags_t com
tree type = NULL_TREE;
bool local_p;
- if (TREE_CODE (t) == TYPE_DECL
- && t == TYPE_MAIN_DECL (TREE_TYPE (t)))
+ if (TREE_CODE (t) == TYPE_DECL)
{
- /* If this is the canonical decl, we don't have to
- mess with instantiations, and often we can't (for
- typename, template type parms and such). Note that
- TYPE_NAME is not correct for the above test if
- we've copied the type for a typedef. */
- type = tsubst (TREE_TYPE (t), args, complain, in_decl);
- if (type == error_mark_node)
+ if (TREE_TYPE (t) == error_mark_node)
RETURN (error_mark_node);
- r = TYPE_NAME (type);
- break;
+ else if (t == TYPE_MAIN_DECL (TREE_TYPE (t)))
+ {
+ /* If this is the canonical decl, we don't have to
+ mess with instantiations, and often we can't (for
+ typename, template type parms and such). Note that
+ TYPE_NAME is not correct for the above test if
+ we've copied the type for a typedef. */
+ type = tsubst (TREE_TYPE (t), args, complain, in_decl);
+ if (type == error_mark_node)
+ RETURN (error_mark_node);
+ r = TYPE_NAME (type);
+ break;
+ }
}
/* Check to see if we already have the specialization we
Index: testsuite/g++.dg/template/crash117.C
===================================================================
--- testsuite/g++.dg/template/crash117.C (revision 0)
+++ testsuite/g++.dg/template/crash117.C (working copy)
@@ -0,0 +1,6 @@
+// PR c++/58448
+
+class SmallVector; struct Types4;
+template <typename, typename, typename, typename> struct Types {
+ typedef Types4<>::Constructable // { dg-error "template|typedef|expected" }
+} Types<SmallVector, SmallVector, SmallVector, SmallVector>:: > // { dg-error "expected" }
More information about the Gcc-patches
mailing list